Skip to content

Commit 5e7b208

Browse files
author
zhengshuxin
committed
Add pre_exit callback before service exiting which is different with the old on_exit callback.
1 parent 9a43386 commit 5e7b208

File tree

18 files changed

+186
-45
lines changed

18 files changed

+186
-45
lines changed

lib_acl/include/master/acl_server_api.h

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,26 +29,27 @@ extern "C" {
2929
#define ACL_MASTER_SERVER_PRE_INIT 10
3030
#define ACL_MASTER_SERVER_POST_INIT 11
3131
#define ACL_MASTER_SERVER_LOOP 12
32-
#define ACL_MASTER_SERVER_EXIT 13
33-
#define ACL_MASTER_SERVER_SOLITARY 14
34-
#define ACL_MASTER_SERVER_UNLIMITED 15
35-
#define ACL_MASTER_SERVER_ON_CLOSE 16
36-
#define ACL_MASTER_SERVER_ON_ACCEPT 17
37-
#define ACL_MASTER_SERVER_ON_TIMEOUT 18
38-
#define ACL_MASTER_SERVER_ON_HANDSHAKE 19
39-
40-
#define ACL_MASTER_SERVER_THREAD_INIT 20
41-
#define ACL_MASTER_SERVER_THREAD_INIT_CTX 21
42-
#define ACL_MASTER_SERVER_THREAD_EXIT 22
43-
#define ACL_MASTER_SERVER_THREAD_EXIT_CTX 23
44-
#define ACL_MASTER_SERVER_CTX 24
45-
#define ACL_MASTER_SERVER_DENY_INFO 25
46-
47-
#define ACL_MASTER_SERVER_EXIT_TIMER 26
48-
#define ACL_MASTER_SERVER_ON_LISTEN 27
32+
#define ACL_MASTER_SERVER_PRE_EXIT 13
33+
#define ACL_MASTER_SERVER_EXIT 14
34+
#define ACL_MASTER_SERVER_SOLITARY 15
35+
#define ACL_MASTER_SERVER_UNLIMITED 16
36+
#define ACL_MASTER_SERVER_ON_CLOSE 17
37+
#define ACL_MASTER_SERVER_ON_ACCEPT 18
38+
#define ACL_MASTER_SERVER_ON_TIMEOUT 19
39+
#define ACL_MASTER_SERVER_ON_HANDSHAKE 20
40+
41+
#define ACL_MASTER_SERVER_THREAD_INIT 21
42+
#define ACL_MASTER_SERVER_THREAD_INIT_CTX 22
43+
#define ACL_MASTER_SERVER_THREAD_EXIT 23
44+
#define ACL_MASTER_SERVER_THREAD_EXIT_CTX 24
45+
#define ACL_MASTER_SERVER_CTX 25
46+
#define ACL_MASTER_SERVER_DENY_INFO 26
47+
48+
#define ACL_MASTER_SERVER_EXIT_TIMER 27
49+
#define ACL_MASTER_SERVER_ON_LISTEN 28
4950
#define ACL_MASTER_SERVER_ON_BIND ACL_MASTER_SERVER_ON_LISTEN
50-
#define ACL_MASTER_SERVER_SIGHUP 28
51-
#define ACL_MASTER_SERVER_ON_UNBIND 29
51+
#define ACL_MASTER_SERVER_SIGHUP 29
52+
#define ACL_MASTER_SERVER_ON_UNBIND 30
5253

5354
#define ACL_APP_CTL_END ACL_MASTER_SERVER_END
5455
#define ACL_APP_CTL_CFG_INT ACL_MASTER_SERVER_INT_TABLE
@@ -71,6 +72,7 @@ extern "C" {
7172
typedef void (*ACL_MASTER_SERVER_INIT_FN) (void *);
7273
typedef int (*ACL_MASTER_SERVER_LOOP_FN) (void *);
7374
typedef void (*ACL_MASTER_SERVER_EXIT_FN) (void *);
75+
typedef int (*ACL_MASTER_SERVER_PRE_EXIT_FN) (void *);
7476
typedef void (*ACL_MASTER_SERVER_ON_LISTEN_FN) (void *, ACL_VSTREAM *);
7577
typedef void (*ACL_MASTER_SERVER_ON_BIND_FN) (void *, ACL_VSTREAM *);
7678
typedef void (*ACL_MASTER_SERVER_ON_UNBIND_FN) (void *, ACL_VSTREAM *);

lib_acl/src/master/template/acl_aio_server.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ static pthread_mutex_t __counter_mutex;
164164

165165
static ACL_AIO_SERVER_FN __service_main;
166166
static ACL_AIO_SERVER2_FN __service2_main;
167+
static ACL_MASTER_SERVER_PRE_EXIT_FN __service_preexit;
167168
static ACL_MASTER_SERVER_EXIT_FN __service_onexit;
168169
static ACL_MASTER_SERVER_ON_LISTEN_FN __service_on_listen;
169170
static ACL_MASTER_SERVER_SIGHUP_FN __sighup_handler;
@@ -328,16 +329,28 @@ static void disable_listen(void)
328329
__sstreams = NULL;
329330
}
330331

332+
static void aio_server_timeout(int type, ACL_EVENT *event, void *context);
333+
331334
/* aio_server_exit - normal termination */
332335

333336
static void aio_server_exit(void)
334337
{
338+
if (__service_preexit && !__service_preexit(__service_ctx)) {
339+
acl_msg_info("%s: prepare exiting", __FUNCTION__);
340+
acl_var_aio_idle_limit = 1;
341+
acl_aio_request_timer(__h_aio, aio_server_timeout, (void*) __h_aio,
342+
(acl_int64) acl_var_aio_idle_limit * 1000000, 0);
343+
return;
344+
}
345+
335346
#ifdef ACL_UNIX
336347
if (acl_var_aio_disable_core_onexit)
337348
acl_set_core_limit(0);
338349
#endif
339350
if (__service_onexit)
340351
__service_onexit(__service_ctx);
352+
353+
acl_msg_info("master disconnect -- exiting");
341354
exit(0);
342355
}
343356

@@ -393,15 +406,13 @@ static void aio_server_abort(ACL_ASTREAM *astream, void *context acl_unused)
393406
__listen_disabled = 1;
394407

395408
if (acl_var_aio_quick_abort) {
396-
acl_msg_info("master disconnect -- exiting");
397409
aio_server_exit();
398410
} else if ((n = get_client_count()) > 0) {
399411
/* set idle timeout to 1 second */
400412
acl_var_aio_idle_limit = 1;
401413
acl_aio_request_timer(__h_aio, aio_server_timeout, (void*) aio,
402414
(acl_int64) acl_var_aio_idle_limit * 1000000, 0);
403415
} else {
404-
acl_msg_info("master disconnect -- exiting");
405416
aio_server_exit();
406417
}
407418
}
@@ -427,6 +438,7 @@ static void aio_server_use_timer(int type acl_unused,
427438
}
428439

429440
acl_msg_info("use limit -- exiting");
441+
430442
aio_server_exit();
431443
}
432444

@@ -1286,7 +1298,7 @@ static void run_loop(const char *procname)
12861298
}
12871299
}
12881300

1289-
/* not reached here */
1301+
/* not reached here */
12901302

12911303
/* acl_vstring_free(buf); */
12921304
/* aio_server_exit(); */
@@ -1408,6 +1420,10 @@ static void server_main(int argc, char **argv, va_list ap)
14081420
case ACL_MASTER_SERVER_POST_INIT:
14091421
post_init = va_arg(ap, ACL_MASTER_SERVER_INIT_FN);
14101422
break;
1423+
case ACL_MASTER_SERVER_PRE_EXIT:
1424+
__service_preexit =
1425+
va_arg(ap, ACL_MASTER_SERVER_PRE_EXIT_FN);
1426+
break;
14111427
case ACL_MASTER_SERVER_EXIT:
14121428
__service_onexit =
14131429
va_arg(ap, ACL_MASTER_SERVER_EXIT_FN);

lib_acl/src/master/template/acl_single_server.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ static ACL_CONFIG_STR_TABLE __conf_str_tab[] = {
116116
*/
117117
static ACL_MASTER_SERVER_ON_LISTEN_FN __service_listen;
118118
static ACL_SINGLE_SERVER_FN __service_main;
119+
static ACL_MASTER_SERVER_PRE_EXIT_FN __service_pre_exit;
119120
static ACL_MASTER_SERVER_EXIT_FN __service_exit;
120121
static ACL_MASTER_SERVER_SIGHUP_FN __sighup_handler;
121122

@@ -159,6 +160,9 @@ static void single_server_exit(void)
159160
acl_set_core_limit(0);
160161
#endif
161162

163+
if (__service_pre_exit)
164+
__service_pre_exit(__service_ctx);
165+
162166
if (__service_exit)
163167
__service_exit(__service_ctx);
164168

@@ -540,6 +544,9 @@ void acl_single_server_main(int argc, char **argv, ACL_SINGLE_SERVER_FN service,
540544
case ACL_MASTER_SERVER_LOOP:
541545
loop = va_arg(ap, ACL_MASTER_SERVER_LOOP_FN);
542546
break;
547+
case ACL_MASTER_SERVER_PRE_EXIT:
548+
__service_pre_exit = va_arg(ap, ACL_MASTER_SERVER_PRE_EXIT_FN);
549+
break;
543550
case ACL_MASTER_SERVER_EXIT:
544551
__service_exit = va_arg(ap, ACL_MASTER_SERVER_EXIT_FN);
545552
break;

lib_acl/src/master/template/acl_threads_server.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ static void *__service_ctx;
186186
static char __service_name[256];
187187
static void (*__server_accept) (int, ACL_EVENT *, ACL_VSTREAM *, void *);
188188
static ACL_THREADS_SERVER_FN __service_main;
189+
static ACL_MASTER_SERVER_PRE_EXIT_FN __server_preexit;
189190
static ACL_MASTER_SERVER_EXIT_FN __server_onexit;
190191
static ACL_MASTER_SERVER_ON_LISTEN_FN __server_on_listen;
191192
static ACL_MASTER_SERVER_ON_ACCEPT_FN __server_on_accept;
@@ -421,15 +422,21 @@ static void server_exiting(int type acl_unused, ACL_EVENT *event, void *ctx)
421422
#endif /* ACL_UNIX */
422423
}
423424

424-
if (__server_exit_timer != NULL
425+
if (__server_preexit && !__server_preexit(__service_ctx)) {
426+
acl_msg_info("%s: prepare exiting, client: %d, threads: %d",
427+
myname, n, nthreads);
428+
acl_event_request_timer(event, server_exiting, ctx, 1000000, 0);
429+
} else if (__server_exit_timer != NULL
425430
&& __server_exit_timer(__service_ctx, n, nthreads) != 0) {
426431

427432
acl_msg_info("%s: master disconnect -- timer exiting, "
428433
"client: %d, threads: %d", myname, n, nthreads);
434+
__server_preexit(__service_ctx);
429435
server_exit();
430436
} else if (n <= 0) {
431437
acl_msg_info("%s: master disconnect -- exiting, "
432438
"clinet: %d, threads: %d", myname, n, nthreads);
439+
__server_preexit(__service_ctx);
433440
server_exit();
434441
} else if (__aborting && acl_var_threads_quick_abort) {
435442
acl_msg_info("%s: master disconnect -- quick exiting, "
@@ -1482,6 +1489,10 @@ void acl_threads_server_main(int argc, char * argv[],
14821489
__server_exit_timer =
14831490
va_arg(ap, ACL_MASTER_SERVER_EXIT_TIMER_FN);
14841491
break;
1492+
case ACL_MASTER_SERVER_PRE_EXIT:
1493+
__server_preexit =
1494+
va_arg(ap, ACL_MASTER_SERVER_PRE_EXIT_FN);
1495+
break;
14851496
case ACL_MASTER_SERVER_EXIT:
14861497
__server_onexit =
14871498
va_arg(ap, ACL_MASTER_SERVER_EXIT_FN);

lib_acl/src/master/template/acl_trigger_server.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,10 @@ static ACL_CONFIG_STR_TABLE __conf_str_tab[] = {
112112
/*
113113
* Global state.
114114
*/
115-
static ACL_TRIGGER_SERVER_FN __service_main;
116-
static ACL_MASTER_SERVER_EXIT_FN __service_exit;
117-
static ACL_MASTER_SERVER_SIGHUP_FN __sighup_handler;
115+
static ACL_TRIGGER_SERVER_FN __service_main;
116+
static ACL_MASTER_SERVER_PRE_EXIT_FN __service_pre_exit;
117+
static ACL_MASTER_SERVER_EXIT_FN __service_exit;
118+
static ACL_MASTER_SERVER_SIGHUP_FN __sighup_handler;
118119
static void (*__service_accept) (int, ACL_EVENT *, ACL_VSTREAM *, void *);
119120

120121
static int use_count;
@@ -140,10 +141,18 @@ ACL_EVENT *acl_trigger_server_event(void)
140141
return __eventp;
141142
}
142143

144+
static void trigger_server_timeout(int type, ACL_EVENT *event, void *context);
145+
143146
/* trigger_server_exit - normal termination */
144147

145148
static void trigger_server_exit(void)
146149
{
150+
if (__service_pre_exit && !__service_pre_exit(__service_ctx)) {
151+
acl_event_request_timer(__eventp, trigger_server_timeout, NULL,
152+
1000000, 0);
153+
return;
154+
}
155+
147156
#ifdef ACL_UNIX
148157
if (acl_var_trigger_disable_core_onexit)
149158
acl_set_core_limit(0);
@@ -518,6 +527,9 @@ void acl_trigger_server_main(int argc, char **argv, ACL_TRIGGER_SERVER_FN servic
518527
case ACL_MASTER_SERVER_LOOP:
519528
loop = va_arg(ap, ACL_MASTER_SERVER_LOOP_FN);
520529
break;
530+
case ACL_MASTER_SERVER_PRE_EXIT:
531+
__service_pre_exit = va_arg(ap, ACL_MASTER_SERVER_PRE_EXIT_FN);
532+
break;
521533
case ACL_MASTER_SERVER_EXIT:
522534
__service_exit = va_arg(ap, ACL_MASTER_SERVER_EXIT_FN);
523535
break;

lib_acl/src/master/template/acl_udp_server.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ typedef struct UDP_SERVER {
153153
* Global state.
154154
*/
155155
static ACL_UDP_SERVER_FN __service_main;
156+
static ACL_MASTER_SERVER_PRE_EXIT_FN __service_pre_exit;
156157
static ACL_MASTER_SERVER_EXIT_FN __service_exit;
157158
static ACL_MASTER_SERVER_THREAD_INIT_FN __thread_init;
158159
static ACL_MASTER_SERVER_SIGHUP_FN __sighup_handler;
@@ -466,12 +467,16 @@ static void servers_stop(void)
466467

467468
/* udp_server_exit - normal termination */
468469

470+
static void udp_server_timeout(int type, ACL_EVENT *event, void *context);
471+
469472
static void udp_server_exit(void)
470473
{
471474
int i;
472475
long long n = 0;
473476

474-
if (__service_exiting) {
477+
if (__service_pre_exit && !__service_pre_exit(__service_ctx)) {
478+
acl_event_request_timer(__main_event,
479+
udp_server_timeout, __main_event, 1000000, 0);
475480
return;
476481
}
477482

@@ -481,6 +486,10 @@ static void udp_server_exit(void)
481486
}
482487
#endif
483488

489+
if (__service_exiting) {
490+
return;
491+
}
492+
484493
__service_exiting = 1;
485494

486495
if (__service_exit)
@@ -1168,6 +1177,9 @@ void acl_udp_server_main(int argc, char **argv, ACL_UDP_SERVER_FN service, ...)
11681177
case ACL_MASTER_SERVER_POST_INIT:
11691178
post_init = va_arg(ap, ACL_MASTER_SERVER_INIT_FN);
11701179
break;
1180+
case ACL_MASTER_SERVER_PRE_EXIT:
1181+
__service_pre_exit = va_arg(ap, ACL_MASTER_SERVER_PRE_EXIT_FN);
1182+
break;
11711183
case ACL_MASTER_SERVER_EXIT:
11721184
__service_exit = va_arg(ap, ACL_MASTER_SERVER_EXIT_FN);
11731185
break;

lib_acl_cpp/include/acl_cpp/master/master_aio.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ class aio_socket_stream;
1717
/**
1818
* acl_master 服务器框架中单线程非阻塞方式的模板类,该类对象只能有一个实例运行
1919
*/
20-
class ACL_CPP_API master_aio : public master_base, public aio_accept_callback
21-
{
20+
class ACL_CPP_API master_aio : public master_base, public aio_accept_callback {
2221
public:
2322
/**
2423
* 开始运行,调用该函数是指该服务进程是在 acl_master 服务框架
@@ -97,6 +96,9 @@ class ACL_CPP_API master_aio : public master_base, public aio_accept_callback
9796
// 当进程切换用户身份后调用的回调函数
9897
static void service_init(void*);
9998

99+
// 当进程退出时调用的回调函数
100+
static int service_pre_exit(void*);
101+
100102
// 当进程退出时调用的回调函数
101103
static void service_exit(void*);
102104

lib_acl_cpp/include/acl_cpp/master/master_base.hpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88

99
struct ACL_EVENT;
1010

11-
namespace acl
12-
{
11+
namespace acl {
1312

1413
class server_socket;
1514
class event_timer;
@@ -18,8 +17,7 @@ class string;
1817
ACL_CPP_API void master_log_enable(bool yes);
1918
ACL_CPP_API bool master_log_enabled(void);
2019

21-
class ACL_CPP_API master_base : public noncopyable
22-
{
20+
class ACL_CPP_API master_base : public noncopyable {
2321
public:
2422
/**
2523
* 设置 bool 类型的配置项
@@ -99,7 +97,16 @@ class ACL_CPP_API master_base : public noncopyable
9997
virtual void proc_on_init() {}
10098

10199
/**
102-
* 当进程退出前调用的回调函数
100+
* 在进程退出前先调用此虚方法,如果子类实现返回 false,则会休眠1秒后
101+
* 继续调用该虚方法,直至子类实现返回 true 为止,这给应用层一个决定
102+
* 是否立刻退出的方法
103+
*
104+
*/
105+
virtual bool proc_pre_exit() { return true; }
106+
107+
/**
108+
* 当进程退出前调用的回调函数,该函数返回后进程将正式退出,注意该方法
109+
* 会在上面 proc_pre_exit 调用后调用
103110
*/
104111
virtual void proc_on_exit() {}
105112

lib_acl_cpp/include/acl_cpp/master/master_proc.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ class socket_stream;
1414
/**
1515
* acl_master 服务器框架中进程方式的模板类,该类对象只能有一个实例运行
1616
*/
17-
class ACL_CPP_API master_proc : public master_base
18-
{
17+
class ACL_CPP_API master_proc : public master_base {
1918
public:
2019
/**
2120
* 开始运行,调用该函数是指该服务进程是在 acl_master 服务框架
@@ -65,6 +64,9 @@ class ACL_CPP_API master_proc : public master_base
6564
// 当进程切换用户身份后调用的回调函数
6665
static void service_init(void*);
6766

67+
// 当进程退出前调用的回调函数
68+
static int service_pre_exit(void*);
69+
6870
// 当进程退出时调用的回调函数
6971
static void service_exit(void*);
7072

lib_acl_cpp/include/acl_cpp/master/master_threads.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ class socket_stream;
1717
* 线程池服务器框架类,该类为纯虚类,子类需要实现其中的纯虚函数,
1818
* 每一个进程仅能有一个该类对象实例,否则程序会被终止
1919
*/
20-
class ACL_CPP_API master_threads : public master_base
21-
{
20+
class ACL_CPP_API master_threads : public master_base {
2221
public:
2322
/**
2423
* 开始运行,调用该函数是指该服务进程是在 acl_master 服务框架
@@ -211,6 +210,9 @@ class ACL_CPP_API master_threads : public master_base
211210
// 当进程需要退出时调用此函数,由应用来确定进程是否需要退出
212211
static int service_exit_timer(void*, size_t, size_t);
213212

213+
// 当进程退出时调用的回调函数
214+
static int service_pre_exit(void*);
215+
214216
// 当进程退出时调用的回调函数
215217
static void service_exit(void*);
216218

0 commit comments

Comments
 (0)