正在显示
1 个修改的文件
包含
151 行增加
和
0 行删除
src/server/spserver/spexecutor.cpp
0 → 100644
1 | +/* | ||
2 | + * Copyright 2007 Stephen Liu | ||
3 | + * For license terms, see the file COPYING along with this library. | ||
4 | + */ | ||
5 | + | ||
6 | + | ||
7 | +#include <sys/types.h> | ||
8 | +#include <assert.h> | ||
9 | + | ||
10 | +#include "spporting.hpp" | ||
11 | + | ||
12 | +#include "spexecutor.hpp" | ||
13 | +#include "spthreadpool.hpp" | ||
14 | + | ||
15 | +#include "sputils.hpp" | ||
16 | + | ||
17 | +SP_Task :: ~SP_Task() | ||
18 | +{ | ||
19 | +} | ||
20 | + | ||
21 | +//=================================================================== | ||
22 | + | ||
23 | +SP_SimpleTask :: SP_SimpleTask( ThreadFunc_t func, void * arg, int deleteAfterRun ) | ||
24 | +{ | ||
25 | + mFunc = func; | ||
26 | + mArg = arg; | ||
27 | + | ||
28 | + mDeleteAfterRun = deleteAfterRun; | ||
29 | +} | ||
30 | + | ||
31 | +SP_SimpleTask :: ~SP_SimpleTask() | ||
32 | +{ | ||
33 | +} | ||
34 | + | ||
35 | +void SP_SimpleTask :: run() | ||
36 | +{ | ||
37 | + mFunc( mArg ); | ||
38 | + | ||
39 | + if( mDeleteAfterRun ) delete this; | ||
40 | +} | ||
41 | + | ||
42 | +//=================================================================== | ||
43 | + | ||
44 | +SP_Executor :: SP_Executor( int maxThreads, const char * tag ) | ||
45 | +{ | ||
46 | + tag = NULL == tag ? "unknown" : tag; | ||
47 | + | ||
48 | + mThreadPool = new SP_ThreadPool( maxThreads, tag ); | ||
49 | + | ||
50 | + mQueue = new SP_BlockingQueue(); | ||
51 | + | ||
52 | + mIsShutdown = 0; | ||
53 | + | ||
54 | + sp_thread_mutex_init( &mMutex, NULL ); | ||
55 | + sp_thread_cond_init( &mCond, NULL ); | ||
56 | + | ||
57 | + sp_thread_attr_t attr; | ||
58 | + sp_thread_attr_init( &attr ); | ||
59 | + assert( sp_thread_attr_setstacksize( &attr, 1024 * 1024 ) == 0 ); | ||
60 | + sp_thread_attr_setdetachstate( &attr, SP_THREAD_CREATE_DETACHED ); | ||
61 | + | ||
62 | + sp_thread_t thread; | ||
63 | + int ret = sp_thread_create( &thread, &attr, eventLoop, this ); | ||
64 | + sp_thread_attr_destroy( &attr ); | ||
65 | + if( 0 == ret ) { | ||
66 | + sp_syslog( LOG_NOTICE, "[ex@%s] Thread #%ld has been created for executor", tag, thread ); | ||
67 | + } else { | ||
68 | + sp_syslog( LOG_WARNING, "[ex@%s] Unable to create a thread for executor", tag ); | ||
69 | + } | ||
70 | +} | ||
71 | + | ||
72 | +SP_Executor :: ~SP_Executor() | ||
73 | +{ | ||
74 | + shutdown(); | ||
75 | + | ||
76 | + while( 2 != mIsShutdown ) { | ||
77 | + sp_thread_mutex_lock( &mMutex ); | ||
78 | + sp_thread_cond_wait( &mCond, &mMutex ); | ||
79 | + sp_thread_mutex_unlock( &mMutex ); | ||
80 | + } | ||
81 | + | ||
82 | + sp_thread_mutex_destroy( &mMutex ); | ||
83 | + sp_thread_cond_destroy( &mCond); | ||
84 | + | ||
85 | + delete mThreadPool; | ||
86 | + mThreadPool = NULL; | ||
87 | + | ||
88 | + delete mQueue; | ||
89 | + mQueue = NULL; | ||
90 | +} | ||
91 | + | ||
92 | +void SP_Executor :: shutdown() | ||
93 | +{ | ||
94 | + sp_thread_mutex_lock( &mMutex ); | ||
95 | + if( 0 == mIsShutdown ) { | ||
96 | + mIsShutdown = 1; | ||
97 | + | ||
98 | + // signal the event loop to wake up | ||
99 | + execute( worker, NULL ); | ||
100 | + } | ||
101 | + sp_thread_mutex_unlock( &mMutex ); | ||
102 | +} | ||
103 | + | ||
104 | +sp_thread_result_t SP_THREAD_CALL SP_Executor :: eventLoop( void * arg ) | ||
105 | +{ | ||
106 | + SP_Executor * executor = ( SP_Executor * )arg; | ||
107 | + | ||
108 | + while( 0 == executor->mIsShutdown ) { | ||
109 | + void * queueData = executor->mQueue->pop(); | ||
110 | + | ||
111 | + if( executor->mThreadPool->getMaxThreads() > 1 ) { | ||
112 | + if( 0 != executor->mThreadPool->dispatch( worker, queueData ) ) { | ||
113 | + worker( queueData ); | ||
114 | + } | ||
115 | + } else { | ||
116 | + worker( queueData ); | ||
117 | + } | ||
118 | + } | ||
119 | + | ||
120 | + sp_thread_mutex_lock( &executor->mMutex ); | ||
121 | + executor->mIsShutdown = 2; | ||
122 | + sp_thread_cond_signal( &executor->mCond ); | ||
123 | + sp_thread_mutex_unlock( &executor->mMutex ); | ||
124 | + | ||
125 | + return 0; | ||
126 | +} | ||
127 | + | ||
128 | +void SP_Executor :: worker( void * arg ) | ||
129 | +{ | ||
130 | + if( NULL != arg ) { | ||
131 | + SP_Task * task = ( SP_Task * )arg; | ||
132 | + task->run(); | ||
133 | + } | ||
134 | +} | ||
135 | + | ||
136 | +void SP_Executor :: execute( SP_Task * task ) | ||
137 | +{ | ||
138 | + mQueue->push( task ); | ||
139 | +} | ||
140 | + | ||
141 | +void SP_Executor :: execute( void ( * func ) ( void * ), void * arg ) | ||
142 | +{ | ||
143 | + SP_SimpleTask * task = new SP_SimpleTask( func, arg, 1 ); | ||
144 | + execute( task ); | ||
145 | +} | ||
146 | + | ||
147 | +int SP_Executor :: getQueueLength() | ||
148 | +{ | ||
149 | + return mQueue->getLength(); | ||
150 | +} | ||
151 | + |
请
注册
或
登录
后发表评论