1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef SOCKET_LISTENER_H
17 #define SOCKET_LISTENER_H
18 
19 #include <map>
20 #include <mutex>
21 #include <thread>
22 #include "sock/socket.h"
23 
24 namespace OHOS {
25 namespace bluetooth {
26 /**
27  * @brief This class is used to create a listener thread.
28  */
29 class SocketThread final {
30 public:
31     static SocketThread &GetInstance();
32 
33     using SocketOptionCallback = void (*)(Socket &sock);
34     /**
35      * @brief Initialize a socket thread.
36      * @details Initialize variables,create socketpair,and add cmd fd to poll.
37      * @return Return int type, greater than 0 success, less than 0 failure.
38      */
39     bool Initialize();
40     /**
41      * @brief Exit a socket thread.
42      * @return bool
43      */
44     bool Uninitialize();
45     /**
46      * @brief Add fd and register callback.
47      * @details Add FD to the thread and register the desired listening state.
48      *          (read, write, exception), and return when the state changes.
49      * @param fd Socket fd.
50      * @param flag Listen event.
51      * @param sock Socket object.
52      * @return bool
53      */
54     bool AddSocket(int fd, int flag, Socket &sock);
55     /**
56      * @brief Delete fd from epoll.
57      * @param sock Socket object.
58      * @return bool
59      */
60     bool DeleteSocket(Socket &sock);
61 
62 private:
63     static const int MAX_EPOLL = 66;
64     SocketThread() = default;
65     ~SocketThread() = default;
66 
67     /**
68      * @brief This function listens to the state of fd in poll all the time.
69      * @details When creating a thread, it will be passed as an argument to
70      *          the function pthread_create().
71      *          It must be void * (*__ start_ Routine) (void *) type.
72      * @return void*
73      */
74     void OnListenEvents(void);
75     /**
76      * @brief Convert the expected event to poll event.
77      * @param flags Status to be detected.
78      * @return unsigned int
79      */
80     uint32_t FlagsChangeEvents(int flags);
81     /**
82      * @brief Find fd from fdMap_.
83      * @param sock Socket object.
84      * @return int
85      */
86     int FindFd(Socket &sock);
87     /**
88      * @brief Delete fd from fdMap_.
89      * @param sock Socket object.
90      * @return void
91      */
92     void DeleteFd(Socket &sock);
93 
94     int epollFd_ {-1};
95     int stopFd_ {-1};
96     int count_ {0};
97 
98     std::mutex mutex_ {};
99     std::mutex epollFdMutex_ {};
100     std::unique_ptr<std::thread> thread_ {};
101 
102     std::map<Socket *, int> fdMap_ {};
103 
104     SocketOptionCallback readCallback_ {Socket::OnSocketReadReady};
105     SocketOptionCallback writeCallback_ {Socket::OnSocketWriteReady};
106     SocketOptionCallback exceptCallback_ {Socket::OnSocketException};
107 };
108 }  // namespace bluetooth
109 }  // namespace OHOS
110 #endif  // SOCKET_LISTENER_H