diff options
Diffstat (limited to 'ot_mutex.c')
-rw-r--r-- | ot_mutex.c | 43 |
1 files changed, 37 insertions, 6 deletions
@@ -14,6 +14,9 @@ | |||
14 | #include "trackerlogic.h" | 14 | #include "trackerlogic.h" |
15 | #include "ot_mutex.h" | 15 | #include "ot_mutex.h" |
16 | 16 | ||
17 | //#define MTX_DBG( STRING ) fprintf( stderr, STRING ) | ||
18 | #define MTX_DBG( STRING ) | ||
19 | |||
17 | /* Our global all torrents list */ | 20 | /* Our global all torrents list */ |
18 | static ot_vector all_torrents[OT_BUCKET_COUNT]; | 21 | static ot_vector all_torrents[OT_BUCKET_COUNT]; |
19 | 22 | ||
@@ -114,14 +117,18 @@ int mutex_workqueue_pushtask( int64 socket, ot_tasktype tasktype ) { | |||
114 | struct ot_task ** tmptask, * task; | 117 | struct ot_task ** tmptask, * task; |
115 | 118 | ||
116 | /* Want exclusive access to tasklist */ | 119 | /* Want exclusive access to tasklist */ |
120 | MTX_DBG( "pushtask locks.\n" ); | ||
117 | pthread_mutex_lock( &tasklist_mutex ); | 121 | pthread_mutex_lock( &tasklist_mutex ); |
122 | MTX_DBG( "pushtask locked.\n" ); | ||
118 | 123 | ||
119 | task = malloc(sizeof( struct ot_task)); | 124 | task = malloc(sizeof( struct ot_task)); |
120 | if( !task ) { | 125 | if( !task ) { |
126 | MTX_DBG( "pushtask fail unlocks.\n" ); | ||
121 | pthread_mutex_unlock( &tasklist_mutex ); | 127 | pthread_mutex_unlock( &tasklist_mutex ); |
128 | MTX_DBG( "pushtask fail unlocked.\n" ); | ||
122 | return -1; | 129 | return -1; |
123 | } | 130 | } |
124 | 131 | ||
125 | /* Skip to end of list */ | 132 | /* Skip to end of list */ |
126 | tmptask = &tasklist; | 133 | tmptask = &tasklist; |
127 | while( *tmptask ) | 134 | while( *tmptask ) |
@@ -136,8 +143,11 @@ int mutex_workqueue_pushtask( int64 socket, ot_tasktype tasktype ) { | |||
136 | task->next = 0; | 143 | task->next = 0; |
137 | 144 | ||
138 | /* Inform waiting workers and release lock */ | 145 | /* Inform waiting workers and release lock */ |
146 | MTX_DBG( "pushtask broadcasts.\n" ); | ||
139 | pthread_cond_broadcast( &tasklist_being_filled ); | 147 | pthread_cond_broadcast( &tasklist_being_filled ); |
148 | MTX_DBG( "pushtask broadcasted, mutex unlocks.\n" ); | ||
140 | pthread_mutex_unlock( &tasklist_mutex ); | 149 | pthread_mutex_unlock( &tasklist_mutex ); |
150 | MTX_DBG( "pushtask end mutex unlocked.\n" ); | ||
141 | return 0; | 151 | return 0; |
142 | } | 152 | } |
143 | 153 | ||
@@ -145,7 +155,9 @@ void mutex_workqueue_canceltask( int64 socket ) { | |||
145 | struct ot_task ** task; | 155 | struct ot_task ** task; |
146 | 156 | ||
147 | /* Want exclusive access to tasklist */ | 157 | /* Want exclusive access to tasklist */ |
158 | MTX_DBG( "canceltask locks.\n" ); | ||
148 | pthread_mutex_lock( &tasklist_mutex ); | 159 | pthread_mutex_lock( &tasklist_mutex ); |
160 | MTX_DBG( "canceltask locked.\n" ); | ||
149 | 161 | ||
150 | task = &tasklist; | 162 | task = &tasklist; |
151 | while( *task && ( (*task)->socket != socket ) ) | 163 | while( *task && ( (*task)->socket != socket ) ) |
@@ -165,7 +177,9 @@ void mutex_workqueue_canceltask( int64 socket ) { | |||
165 | } | 177 | } |
166 | 178 | ||
167 | /* Release lock */ | 179 | /* Release lock */ |
180 | MTX_DBG( "canceltask unlocks.\n" ); | ||
168 | pthread_mutex_unlock( &tasklist_mutex ); | 181 | pthread_mutex_unlock( &tasklist_mutex ); |
182 | MTX_DBG( "canceltask unlocked.\n" ); | ||
169 | } | 183 | } |
170 | 184 | ||
171 | ot_taskid mutex_workqueue_poptask( ot_tasktype tasktype ) { | 185 | ot_taskid mutex_workqueue_poptask( ot_tasktype tasktype ) { |
@@ -173,7 +187,9 @@ ot_taskid mutex_workqueue_poptask( ot_tasktype tasktype ) { | |||
173 | ot_taskid taskid = 0; | 187 | ot_taskid taskid = 0; |
174 | 188 | ||
175 | /* Want exclusive access to tasklist */ | 189 | /* Want exclusive access to tasklist */ |
190 | MTX_DBG( "poptask mutex locks.\n" ); | ||
176 | pthread_mutex_lock( &tasklist_mutex ); | 191 | pthread_mutex_lock( &tasklist_mutex ); |
192 | MTX_DBG( "poptask mutex locked.\n" ); | ||
177 | 193 | ||
178 | while( !taskid ) { | 194 | while( !taskid ) { |
179 | /* Skip to the first unassigned task this worker wants to do */ | 195 | /* Skip to the first unassigned task this worker wants to do */ |
@@ -185,15 +201,18 @@ ot_taskid mutex_workqueue_poptask( ot_tasktype tasktype ) { | |||
185 | and leave the loop */ | 201 | and leave the loop */ |
186 | if( task ) { | 202 | if( task ) { |
187 | task->taskid = taskid = ++next_free_taskid; | 203 | task->taskid = taskid = ++next_free_taskid; |
188 | break; | 204 | } else { |
205 | /* Wait until the next task is being fed */ | ||
206 | MTX_DBG( "poptask cond waits.\n" ); | ||
207 | pthread_cond_wait( &tasklist_being_filled, &tasklist_mutex ); | ||
208 | MTX_DBG( "poptask cond waited.\n" ); | ||
189 | } | 209 | } |
190 | |||
191 | /* Wait until the next task is being fed */ | ||
192 | pthread_cond_wait( &tasklist_being_filled, &tasklist_mutex ); | ||
193 | } | 210 | } |
194 | 211 | ||
195 | /* Release lock */ | 212 | /* Release lock */ |
213 | MTX_DBG( "poptask end mutex unlocks.\n" ); | ||
196 | pthread_mutex_unlock( &tasklist_mutex ); | 214 | pthread_mutex_unlock( &tasklist_mutex ); |
215 | MTX_DBG( "poptask end mutex unlocked.\n" ); | ||
197 | 216 | ||
198 | return taskid; | 217 | return taskid; |
199 | } | 218 | } |
@@ -201,7 +220,9 @@ ot_taskid mutex_workqueue_poptask( ot_tasktype tasktype ) { | |||
201 | int mutex_workqueue_pushresult( ot_taskid taskid, int iovec_entries, struct iovec *iovec ) { | 220 | int mutex_workqueue_pushresult( ot_taskid taskid, int iovec_entries, struct iovec *iovec ) { |
202 | struct ot_task * task; | 221 | struct ot_task * task; |
203 | /* Want exclusive access to tasklist */ | 222 | /* Want exclusive access to tasklist */ |
223 | MTX_DBG( "pushresult locks.\n" ); | ||
204 | pthread_mutex_lock( &tasklist_mutex ); | 224 | pthread_mutex_lock( &tasklist_mutex ); |
225 | MTX_DBG( "pushresult locked.\n" ); | ||
205 | 226 | ||
206 | task = tasklist; | 227 | task = tasklist; |
207 | while( task && ( task->taskid != taskid ) ) | 228 | while( task && ( task->taskid != taskid ) ) |
@@ -214,7 +235,9 @@ int mutex_workqueue_pushresult( ot_taskid taskid, int iovec_entries, struct iove | |||
214 | } | 235 | } |
215 | 236 | ||
216 | /* Release lock */ | 237 | /* Release lock */ |
238 | MTX_DBG( "pushresult unlocks.\n" ); | ||
217 | pthread_mutex_unlock( &tasklist_mutex ); | 239 | pthread_mutex_unlock( &tasklist_mutex ); |
240 | MTX_DBG( "pushresult unlocked.\n" ); | ||
218 | 241 | ||
219 | /* Indicate whether the worker has to throw away results */ | 242 | /* Indicate whether the worker has to throw away results */ |
220 | return task ? 0 : -1; | 243 | return task ? 0 : -1; |
@@ -225,11 +248,13 @@ int64 mutex_workqueue_popresult( int *iovec_entries, struct iovec ** iovec ) { | |||
225 | int64 socket = -1; | 248 | int64 socket = -1; |
226 | 249 | ||
227 | /* Want exclusive access to tasklist */ | 250 | /* Want exclusive access to tasklist */ |
251 | MTX_DBG( "popresult locks.\n" ); | ||
228 | pthread_mutex_lock( &tasklist_mutex ); | 252 | pthread_mutex_lock( &tasklist_mutex ); |
253 | MTX_DBG( "popresult locked.\n" ); | ||
229 | 254 | ||
230 | task = &tasklist; | 255 | task = &tasklist; |
231 | while( *task && ( (*task)->tasktype != OT_TASKTYPE_DONE ) ) | 256 | while( *task && ( (*task)->tasktype != OT_TASKTYPE_DONE ) ) |
232 | *task = (*task)->next; | 257 | task = &(*task)->next; |
233 | 258 | ||
234 | if( *task && ( (*task)->tasktype == OT_TASKTYPE_DONE ) ) { | 259 | if( *task && ( (*task)->tasktype == OT_TASKTYPE_DONE ) ) { |
235 | struct ot_task *ptask = *task; | 260 | struct ot_task *ptask = *task; |
@@ -243,11 +268,15 @@ int64 mutex_workqueue_popresult( int *iovec_entries, struct iovec ** iovec ) { | |||
243 | } | 268 | } |
244 | 269 | ||
245 | /* Release lock */ | 270 | /* Release lock */ |
271 | MTX_DBG( "popresult unlocks.\n" ); | ||
246 | pthread_mutex_unlock( &tasklist_mutex ); | 272 | pthread_mutex_unlock( &tasklist_mutex ); |
273 | MTX_DBG( "popresult unlocked.\n" ); | ||
247 | return socket; | 274 | return socket; |
248 | } | 275 | } |
249 | 276 | ||
250 | void mutex_init( ) { | 277 | void mutex_init( ) { |
278 | pthread_mutex_init(&tasklist_mutex, NULL); | ||
279 | pthread_cond_init (&tasklist_being_filled, NULL); | ||
251 | pthread_mutex_init(&bucket_mutex, NULL); | 280 | pthread_mutex_init(&bucket_mutex, NULL); |
252 | pthread_cond_init (&bucket_being_unlocked, NULL); | 281 | pthread_cond_init (&bucket_being_unlocked, NULL); |
253 | byte_zero( all_torrents, sizeof( all_torrents ) ); | 282 | byte_zero( all_torrents, sizeof( all_torrents ) ); |
@@ -256,5 +285,7 @@ void mutex_init( ) { | |||
256 | void mutex_deinit( ) { | 285 | void mutex_deinit( ) { |
257 | pthread_mutex_destroy(&bucket_mutex); | 286 | pthread_mutex_destroy(&bucket_mutex); |
258 | pthread_cond_destroy(&bucket_being_unlocked); | 287 | pthread_cond_destroy(&bucket_being_unlocked); |
288 | pthread_mutex_destroy(&tasklist_mutex); | ||
289 | pthread_cond_destroy(&tasklist_being_filled); | ||
259 | byte_zero( all_torrents, sizeof( all_torrents ) ); | 290 | byte_zero( all_torrents, sizeof( all_torrents ) ); |
260 | } | 291 | } |