正在显示
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 | + | ... | ... |
请
注册
或
登录
后发表评论