acl  3.5.3.0
rpc.hpp
浏览该文件的文档.
1 #pragma once
2 #include "../acl_cpp_define.hpp"
3 #include "ipc_service.hpp"
4 #if defined(_WIN32) || defined(_WIN64)
5  struct acl_pthread_mutex_t;
6  struct acl_pthread_cond_t;
7 #else
8 # include <pthread.h>
9 # ifndef acl_pthread_mutex_t
10 # define acl_pthread_mutex_t pthread_mutex_t
11 # endif
12 # ifndef acl_pthread_cond_t
13 # define acl_pthread_cond_t pthread_cond_t
14 # endif
15 #endif
16 
17 namespace acl {
18 
19 class ipc_client;
20 class rpc_client;
21 class rpc_service;
22 
23 class rpc_request;
24 struct RPC_DAT
25 {
27  void* ctx;
28 };
29 
31 {
32 public:
33  rpc_request(void);
34  virtual ~rpc_request(void);
35 
36 protected:
37  friend class rpc_client;
38  friend class rpc_service;
39 
40  /**
41  * 在主线程中被调用,子类必须实现此接口,
42  * 当子线程处理完请求任务后该接口将被调用,所以该类对象只能
43  * 是当本接口调用后才能被释放,禁止在调用本接口前释放本类对象
44  */
45  virtual void rpc_onover(void) = 0;
46 
47  /**
48  * 虚接口:当子线程调用本对象的 rpc_signal 时,在主线程中会
49  * 调用本接口,通知在任务未完成前(即调用 rpc_onover 前)收到
50  * 子线程运行的中间状态信息;内部自动支持套接口或 _WIN32 窗口
51  * 消息;应用场景,例如,对于 HTTP 下载应用,在子线程中可以
52  * 一边下载,一边向主线程发送(调用 rpc_signal 方法)下载进程,
53  * 则主线程会调用本类实例的此方法来处理此消息
54  */
55  virtual void rpc_wakeup(void* ctx) { (void) ctx; }
56 
57 protected:
58  /**
59  * 在子线程中被调用,子类必须实现此接口,用于处理具体任务
60  */
61  virtual void rpc_run(void) = 0;
62 
63  /**
64  * 在子线程中被调用,内部自动支持套接口或 _WIN32 窗口消息
65  * 子类实例的 rpc_run 方法中可以多次调用此方法向主线程的
66  * 本类实例发送消息,主线程中调用本对象 rpc_wakeup 方法
67  * @param ctx {void*} 传递的参数指针,一般应该是动态地址
68  * 比较好,这样可以避免同一个参数被重复覆盖的问题
69  */
70  void rpc_signal(void* ctx);
71 
72  /**
73  * 当子线程调用 rpc_signal 给主线程后,调用本方法可以等待
74  * 主线程发来下一步指令
75  * @param timeout {int} 等待超时时间(毫秒),当该值为 0 时
76  * 则采用非阻塞等待模式,当该值为 < 0 时,则采用完全阻塞
77  * 等待模式(即一直等到主线程发送 cond_signal 通知),当该
78  * 值 > 0 时,则等待的最大超时时间为 timeout 毫秒
79  * @return {bool} 返回 true 表示收到主线程发来的通知信号,
80  * 否则,需要调用 cond_wait_timeout 判断是否是超时引起的
81  */
82  bool cond_wait(int timeout = -1);
83 
84  /**
85  * 当 cond_wait 返回 false 时,应用应该调用本方法判断是否
86  * 是因为等待超时引起的
87  * @return {bool} 是否是等待超时
88  */
89  bool cond_wait_timeout() const
90  {
91  return wait_timedout_;
92  }
93 
94  /**
95  * 当子线程调用 cond_wait 时,在主线程中调用本方法通知子线程
96  * “醒来”
97  * @return {bool} 当有子线程调用 cond_wait 时本函数通知子线程
98  * “醒来”并且返回 true,否则返回 false
99  */
100  bool cond_signal(void);
101 
102 private:
103  RPC_DAT dat_;
104  ipc_client* ipc_;
105  int cond_count_;
106  acl_pthread_mutex_t* lock_;
107  acl_pthread_cond_t* cond_;
108  bool wait_timedout_;
109 
110  // 基类 ipc_request 虚函数,在子线程中被调用
111  virtual void run(ipc_client* ipc);
112 #if defined(_WIN32) || defined(_WIN64)
113  /**
114  * 虚接口,子类实现此类用于处理具体的任务,该接口适用
115  * 于采用 _WIN32 消息的模式
116  * @param hWnd {HWND} WIN2 窗口句柄
117  */
118  virtual void run(HWND hWnd);
119 #endif
120 };
121 
122 //////////////////////////////////////////////////////////////////////////
123 
124 class aio_socket_stream;
125 
127 {
128 public:
129  /**
130  * 构造函数
131  * @param nthread {int} 如果该值 > 1 则内部自动采用线程池,否则
132  * 则是一个请求一个线程
133  * @param ipc_keep {bool} 内部 IPC 消息流是否保持长连接,保持长
134  * 连接有助于提高消息传递的效率
135  */
136  rpc_service(int nthread, bool ipc_keep = true);
137 
138  ~rpc_service(void) {}
139 
140  /**
141  * 主线程中运行:将请求任务放入子线程池的任务请求队列中,当线程池
142  * 中的一个子线程接收到该任务后便调用 rpc_request::rpc_run 方法调
143  * 用子类的方法,当任务处理完毕后给主线程发消息,在主线程中再调用
144  * rpc_request::rpc_callback
145  * @param req {rpc_request*} rpc_request 子类实例,非空
146  */
147  void rpc_fork(rpc_request* req);
148 
149 private:
150  // 基类虚函数:主线程对象接收到子线程消息的
151  // ipc 连接请求时的回调函数
152  virtual void on_accept(aio_socket_stream* client);
153 
154 #if defined(_WIN32) || defined(_WIN64)
155  /**
156  * 基类虚函数,当收到来自于子线程的 win32 消息时的回调函数
157  * @param hWnd {HWND} 窗口句柄
158  * @param msg {UINT} 用户自定义消息号
159  * @param wParam {WPARAM} 参数
160  * @param lParam {LPARAM} 参数
161  */
162  virtual void win32_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
163 #endif
164 };
165 
166 } // namespace acl
~rpc_service(void)
Definition: rpc.hpp:138
virtual void rpc_wakeup(void *ctx)
Definition: rpc.hpp:55
bool cond_wait_timeout() const
Definition: rpc.hpp:89
void * ctx
Definition: rpc.hpp:27
#define ACL_CPP_API
rpc_request * req
Definition: rpc.hpp:26