uv_ipc_common.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. #ifndef uv_ipc_common_h
  2. #define uv_ipc_common_h
  3. #include "uv.h"
  4. #include <string>
  5. #include <list>
  6. #include <vector>
  7. //#define USING_ASYNC_IN_MSGCALLBACK
  8. class UVIPCLocker
  9. {
  10. public:
  11. UVIPCLocker()
  12. {
  13. uv_rwlock_init(&uv_rw_locker);
  14. }
  15. virtual ~UVIPCLocker()
  16. {
  17. uv_rwlock_destroy(&uv_rw_locker);
  18. }
  19. void Lock(bool write = true);
  20. void Unlock(bool write = true);
  21. private:
  22. uv_rwlock_t uv_rw_locker;
  23. };
  24. #ifdef _WIN32
  25. #include <windows.h>
  26. typedef LONG UVAtmInt;
  27. # define uv_atomic_inc ::InterlockedIncrement
  28. # define uv_atomic_dec ::InterlockedDecrement
  29. #elif (defined __linux)
  30. typedef int32_t UVAtmInt;
  31. #define uv_atomic_inc(x) __sync_add_and_fetch((x), 1)
  32. #define uv_atomic_dec(x) __sync_sub_and_fetch((x), 1)
  33. #else//now only support win and mac
  34. #include <libkern/OSAtomic.h>
  35. typedef int32_t UVAtmInt;
  36. # define uv_atomic_inc OSAtomicIncrement32
  37. # define uv_atomic_dec OSAtomicDecrement32
  38. #endif
  39. class UVCAtomicInt
  40. {
  41. private:
  42. UVAtmInt m_nVal;
  43. public:
  44. UVCAtomicInt (long n = 0) : m_nVal (n) {}
  45. UVAtmInt Inc () { return uv_atomic_inc (&m_nVal); }
  46. UVAtmInt Dec () { return uv_atomic_dec (&m_nVal); }
  47. long Get () const { return m_nVal; }
  48. };
  49. #define UVIPC_MSG_HEADER_LEN (sizeof(unsigned long long)+sizeof(int))
  50. class UVIPCMessage
  51. {
  52. public:
  53. explicit UVIPCMessage(const char* in_buf, int in_len, bool using_external_buffer_ = false);
  54. char* GetBuf();
  55. int GetLen();
  56. char* GetRealBuf();
  57. int GetRealLen();
  58. virtual bool AddRef()
  59. {
  60. if (ref_count.Get() > 0)
  61. {
  62. ref_count.Inc();
  63. return true;
  64. }
  65. return false;
  66. }
  67. virtual int Release()
  68. {
  69. if (ref_count.Get() <= 0)
  70. return 0;
  71. int ref_ = ref_count.Dec();
  72. if (ref_ == 0)
  73. {
  74. delete this;
  75. }
  76. return ref_;
  77. }
  78. protected:
  79. virtual ~UVIPCMessage();
  80. private:
  81. char* buf;
  82. int len;
  83. UVCAtomicInt ref_count;
  84. bool using_external_buffer;
  85. };
  86. #if (defined _WIN32)
  87. class RUNTIMECOUNTER
  88. {
  89. public:
  90. RUNTIMECOUNTER(){
  91. time=0;
  92. }
  93. virtual ~RUNTIMECOUNTER(){}
  94. void start()
  95. {
  96. QueryPerformanceFrequency(&nFreq);
  97. QueryPerformanceCounter(&nBeginTime);
  98. }
  99. int end()
  100. {
  101. QueryPerformanceCounter(&nEndTime);
  102. time=(double)(nEndTime.QuadPart-nBeginTime.QuadPart)/(double)nFreq.QuadPart;
  103. return (int)time*1000;
  104. }
  105. private:
  106. double time;
  107. LARGE_INTEGER nFreq;
  108. LARGE_INTEGER nBeginTime;
  109. LARGE_INTEGER nEndTime;
  110. };
  111. #endif
  112. class UVIPCSink
  113. {
  114. public:
  115. virtual void onConnect() = 0;
  116. virtual void onDisconnect() = 0;
  117. virtual void onMessageRecvNotification(UVIPCMessage* msg) = 0;
  118. virtual void onIdle() = 0;
  119. };
  120. class UVIPC
  121. {
  122. public:
  123. friend void on_pipe_client_connection_cb(uv_stream_t* server,int status);
  124. friend void on_pipe_data_read_cb(uv_stream_t* client,ssize_t nread,const uv_buf_t* buf);
  125. friend void on_server_connected_cb(uv_connect_t* req,int status);
  126. friend void on_write_data_cb(uv_write_t* req,int status);
  127. friend void uv_ipc_timer_cb(uv_timer_t* handle);
  128. UVIPC();
  129. virtual ~UVIPC();
  130. virtual bool Start(char* name_, bool is_server, uv_loop_t* loop_, UVIPCSink* sink_, uv_loop_t* loop_msg_callback = NULL);
  131. virtual bool Stop();
  132. virtual bool IsRunning(bool check_connection = false);
  133. virtual bool SendMessage(const char* buf, int len);
  134. virtual bool SendMessage(UVIPCMessage* msg);
  135. private:
  136. #ifdef USING_ASYNC_IN_MSGCALLBACK
  137. void SignalMsgCallbackThread();
  138. static void msg_callback_thread_sync_proc(uv_async_t* handle);
  139. #else
  140. void StartMsgCallbackTimer(uv_loop_t* msg_callback_loop);
  141. static void start_msg_callback_timer_sync_proc(uv_async_t* handle);
  142. #endif
  143. private:
  144. typedef struct _UVIPCData
  145. {
  146. uv_pipe_t handle;
  147. UVIPC* owner;
  148. std::string uv_pipe_name;
  149. bool is_server_mode;
  150. uv_loop_t* uv_looper;
  151. UVIPCSink* external_sink;
  152. typedef struct _ServerPart
  153. {
  154. uv_pipe_t* client;
  155. }ServerPart;
  156. typedef struct _ClientPart
  157. {
  158. uv_connect_t* connect;
  159. }ClientPart;
  160. union PART
  161. {
  162. ClientPart part_c;
  163. ServerPart part_s;
  164. }ut;
  165. _UVIPCData()
  166. {
  167. owner = NULL;
  168. is_server_mode = false;
  169. uv_looper = NULL;
  170. external_sink = NULL;
  171. ut.part_c.connect = NULL;
  172. ut.part_s.client = NULL;
  173. }
  174. }UVIPCData;
  175. enum UVIPCTimerType
  176. {
  177. none_timer = 0,
  178. send_msg_timer = 1,
  179. recv_msg_timer = 2,
  180. };
  181. typedef struct _UVIPCTimerData
  182. {
  183. uv_timer_t uv_timer_req;
  184. UVIPC* owener;
  185. UVIPCData* owner_ipc_data;
  186. UVIPCTimerType type;
  187. _UVIPCTimerData()
  188. {
  189. owener = NULL;
  190. type = none_timer;
  191. }
  192. }UVIPCTimerData;
  193. bool StartWithServer(char* name_, bool is_server, uv_loop_t* loop_);
  194. void uv_cb_client_connection_notify(uv_stream_t* server, int status);
  195. bool StartWithClient(char* name_, bool is_server, uv_loop_t* loop_);
  196. void uv_cb_server_connected_notify(uv_connect_t* req,int status);
  197. void uv_cb_pipe_data_write(uv_write_t* req,int status);
  198. void uv_cb_pipe_data_read(uv_stream_t* client,ssize_t nread,const uv_buf_t* buf);
  199. void uv_cb_ipc_sendmsg_timer(uv_timer_t* handle);
  200. void HandleMessageRecvNotification(UVIPCMessage* msg);
  201. #ifndef USING_ASYNC_IN_MSGCALLBACK
  202. void uv_cb_ipc_recvmsg_timer(uv_timer_t* handle);
  203. #endif
  204. void HandleUVMsgCallback(UVIPCSink* external_sink);
  205. UVIPCData uv_data;
  206. UVIPCTimerData uv_timer_data;
  207. #ifndef USING_ASYNC_IN_MSGCALLBACK
  208. UVIPCTimerData msg_callback_uv_timer_data;
  209. #else
  210. uv_async_t _msg_callback_event;
  211. #endif
  212. UVIPCLocker outmsg_locker;
  213. std::list<UVIPCMessage* > outmsg_list;
  214. char* buffered_ipc_msg;
  215. int buffered_ipc_msg_offset;
  216. UVIPCLocker inmsg_locker;
  217. std::list<UVIPCMessage* > inmsg_list;
  218. uv_loop_t* _msg_callback_loop;
  219. #ifndef USING_ASYNC_IN_MSGCALLBACK
  220. std::vector<uv_async_t* > async_handle_list;
  221. #endif
  222. };
  223. class UVIPCInSubThread : public UVIPC
  224. {
  225. public:
  226. UVIPCInSubThread();
  227. virtual ~UVIPCInSubThread();
  228. virtual bool StartInSubThread(char* name_, bool is_server, UVIPCSink* sink_, uv_loop_t* msg_callback_loop_ = NULL);
  229. virtual bool Stop();
  230. bool IsSubThreadRunning() { return _running; }
  231. private:
  232. void Reset();
  233. static void work_thread_sync_proc(uv_async_t* handle);
  234. static void work_thread_proc(void* param);
  235. //call from sub thread
  236. void BeforeSubThreadLoopRun();
  237. void AfterSubThreadLoopRun();
  238. //
  239. virtual bool Start(char* name_, bool is_server, uv_loop_t* loop_, UVIPCSink* sink_, uv_loop_t* loop_msg_callback = NULL) { return false; };
  240. bool _is_server_mode;
  241. uv_async_t _async;
  242. std::string _pipe_name;
  243. uv_loop_t* _sub_thread_loop;
  244. uv_loop_t* _msg_callback_loop;
  245. UVIPCSink* _sink;
  246. uv_sem_t sem_start_thread;
  247. uv_sem_t sem_stop_thread;
  248. bool _running;
  249. int _action;
  250. };
  251. #endif