60
60
/* The queue is a linked list of these. */
61
61
62
62
static struct dlq_item_s * queue_head = NULL ; /* Head of linked list for queue. */
63
+ static struct dlq_item_s * queue_tail = NULL ; /* Tail of linked list for queue. */
64
+ int queue_length = 0 ; /* Count of items in queue */
63
65
64
66
#if __WIN32__
65
67
@@ -75,8 +77,6 @@ static pthread_mutex_t dlq_mutex; /* Critical section for updating queues. */
75
77
76
78
static pthread_cond_t wake_up_cond ; /* Notify received packet processing thread when queue not empty. */
77
79
78
- static pthread_mutex_t wake_up_mutex ; /* Required by cond_wait. */
79
-
80
80
static volatile int recv_thread_is_waiting = 0 ;
81
81
82
82
#endif
@@ -117,7 +117,8 @@ void dlq_init (void)
117
117
dw_printf ("dlq_init ( )\n" );
118
118
#endif
119
119
120
- queue_head = NULL ;
120
+ queue_head = queue_tail = NULL ;
121
+ queue_length = 0 ;
121
122
122
123
123
124
#if DEBUG
@@ -129,13 +130,6 @@ void dlq_init (void)
129
130
InitializeCriticalSection (& dlq_cs );
130
131
#else
131
132
int err ;
132
- err = pthread_mutex_init (& wake_up_mutex , NULL );
133
- if (err != 0 ) {
134
- text_color_set (DW_COLOR_ERROR );
135
- dw_printf ("dlq_init: pthread_mutex_init err=%d" , err );
136
- perror ("" );
137
- exit (EXIT_FAILURE );
138
- }
139
133
err = pthread_mutex_init (& dlq_mutex , NULL );
140
134
if (err != 0 ) {
141
135
text_color_set (DW_COLOR_ERROR );
@@ -314,9 +308,6 @@ void dlq_rec_frame (int chan, int subchan, int slice, packet_t pp, alevel_t alev
314
308
315
309
static void append_to_queue (struct dlq_item_s * pnew )
316
310
{
317
- struct dlq_item_s * plast ;
318
- int queue_length = 0 ;
319
-
320
311
if ( ! was_init ) {
321
312
dlq_init ();
322
313
}
@@ -341,30 +332,19 @@ static void append_to_queue (struct dlq_item_s *pnew)
341
332
#endif
342
333
343
334
if (queue_head == NULL ) {
344
- queue_head = pnew ;
335
+ assert (queue_tail == NULL );
336
+ queue_head = queue_tail = pnew ;
345
337
queue_length = 1 ;
338
+ } else {
339
+ assert (queue_tail != NULL );
340
+ queue_tail -> nextp = pnew ;
341
+ queue_tail = pnew ;
342
+ queue_length ++ ;
343
+ assert (queue_length > 1 );
346
344
}
347
- else {
348
- queue_length = 2 ; /* head + new one */
349
- plast = queue_head ;
350
- while (plast -> nextp != NULL ) {
351
- plast = plast -> nextp ;
352
- queue_length ++ ;
353
- }
354
- plast -> nextp = pnew ;
355
- }
356
-
357
345
358
346
#if __WIN32__
359
347
LeaveCriticalSection (& dlq_cs );
360
- #else
361
- err = pthread_mutex_unlock (& dlq_mutex );
362
- if (err != 0 ) {
363
- text_color_set (DW_COLOR_ERROR );
364
- dw_printf ("dlq append_to_queue: pthread_mutex_unlock err=%d" , err );
365
- perror ("" );
366
- exit (1 );
367
- }
368
348
#endif
369
349
#if DEBUG1
370
350
text_color_set (DW_COLOR_DEBUG );
@@ -416,7 +396,7 @@ static void append_to_queue (struct dlq_item_s *pnew)
416
396
* and blocking on a write.
417
397
*/
418
398
419
- if (queue_length > 10 ) {
399
+ if (queue_length > 15 ) {
420
400
text_color_set (DW_COLOR_ERROR );
421
401
dw_printf ("Received frame queue is out of control. Length=%d.\n" , queue_length );
422
402
dw_printf ("Reader thread is probably frozen.\n" );
@@ -431,29 +411,21 @@ static void append_to_queue (struct dlq_item_s *pnew)
431
411
#else
432
412
if (recv_thread_is_waiting ) {
433
413
434
- err = pthread_mutex_lock (& wake_up_mutex );
435
- if (err != 0 ) {
436
- text_color_set (DW_COLOR_ERROR );
437
- dw_printf ("dlq append_to_queue: pthread_mutex_lock wu err=%d" , err );
438
- perror ("" );
439
- exit (1 );
440
- }
441
-
442
414
err = pthread_cond_signal (& wake_up_cond );
443
415
if (err != 0 ) {
444
416
text_color_set (DW_COLOR_ERROR );
445
417
dw_printf ("dlq append_to_queue: pthread_cond_signal err=%d" , err );
446
418
perror ("" );
447
419
exit (1 );
448
420
}
421
+ }
449
422
450
- err = pthread_mutex_unlock (& wake_up_mutex );
451
- if (err != 0 ) {
452
- text_color_set (DW_COLOR_ERROR );
453
- dw_printf ("dlq append_to_queue: pthread_mutex_unlock wu err=%d" , err );
454
- perror ("" );
455
- exit (1 );
456
- }
423
+ err = pthread_mutex_unlock (& dlq_mutex );
424
+ if (err != 0 ) {
425
+ text_color_set (DW_COLOR_ERROR );
426
+ dw_printf ("dlq append_to_queue: pthread_mutex_unlock wu err=%d" , err );
427
+ perror ("" );
428
+ exit (1 );
457
429
}
458
430
#endif
459
431
@@ -1011,9 +983,29 @@ int dlq_wait_while_empty (double timeout)
1011
983
dlq_init ();
1012
984
}
1013
985
986
+ #if DEBUG1
987
+ text_color_set (DW_COLOR_DEBUG );
988
+ dw_printf ("dlq dlq_wait_while_empty: enter critical section\n" );
989
+ #endif
990
+ #if __WIN32__
991
+ EnterCriticalSection (& dlq_cs );
992
+ #else
993
+ int err ;
994
+ err = pthread_mutex_lock (& dlq_mutex );
995
+ if (err != 0 ) {
996
+ text_color_set (DW_COLOR_ERROR );
997
+ dw_printf ("dlq append_to_queue: pthread_mutex_lock err=%d" , err );
998
+ perror ("" );
999
+ exit (1 );
1000
+ }
1001
+ #endif
1014
1002
1015
1003
if (queue_head == NULL ) {
1016
1004
1005
+ #if __WIN32__
1006
+ LeaveCriticalSection (& dlq_cs );
1007
+ #endif
1008
+
1017
1009
#if DEBUG
1018
1010
text_color_set (DW_COLOR_DEBUG );
1019
1011
dw_printf ("dlq_wait_while_empty (): prepare to SLEEP...\n" );
@@ -1037,45 +1029,41 @@ int dlq_wait_while_empty (double timeout)
1037
1029
else {
1038
1030
WaitForSingleObject (wake_up_event , INFINITE );
1039
1031
}
1032
+ } else {
1033
+ #if __WIN32__
1034
+ LeaveCriticalSection (& dlq_cs );
1035
+ #endif
1036
+ }
1040
1037
1041
1038
#else
1042
1039
int err ;
1043
1040
1044
- err = pthread_mutex_lock (& wake_up_mutex );
1045
- if (err != 0 ) {
1046
- text_color_set (DW_COLOR_ERROR );
1047
- dw_printf ("dlq_wait_while_empty: pthread_mutex_lock wu err=%d" , err );
1048
- perror ("" );
1049
- exit (1 );
1050
- }
1051
-
1052
1041
recv_thread_is_waiting = 1 ;
1053
1042
if (timeout != 0.0 ) {
1054
1043
struct timespec abstime ;
1055
1044
1056
1045
abstime .tv_sec = (time_t )(long )timeout ;
1057
1046
abstime .tv_nsec = (long )((timeout - (long )abstime .tv_sec ) * 1000000000.0 );
1058
1047
1059
- err = pthread_cond_timedwait (& wake_up_cond , & wake_up_mutex , & abstime );
1048
+ err = pthread_cond_timedwait (& wake_up_cond , & dlq_mutex , & abstime );
1060
1049
if (err == ETIMEDOUT ) {
1061
1050
timed_out_result = 1 ;
1062
1051
}
1063
1052
}
1064
1053
else {
1065
- err = pthread_cond_wait (& wake_up_cond , & wake_up_mutex );
1054
+ err = pthread_cond_wait (& wake_up_cond , & dlq_mutex );
1066
1055
}
1067
1056
recv_thread_is_waiting = 0 ;
1068
-
1069
- err = pthread_mutex_unlock (& wake_up_mutex );
1070
- if (err != 0 ) {
1071
- text_color_set (DW_COLOR_ERROR );
1072
- dw_printf ("dlq_wait_while_empty: pthread_mutex_unlock wu err=%d" , err );
1073
- perror ("" );
1074
- exit (1 );
1075
- }
1076
- #endif
1077
1057
}
1078
1058
1059
+ err = pthread_mutex_unlock (& dlq_mutex );
1060
+ if (err != 0 ) {
1061
+ text_color_set (DW_COLOR_ERROR );
1062
+ dw_printf ("dlq_wait_while_empty: pthread_mutex_unlock wu err=%d" , err );
1063
+ perror ("" );
1064
+ exit (1 );
1065
+ }
1066
+ #endif
1079
1067
1080
1068
#if DEBUG
1081
1069
text_color_set (DW_COLOR_DEBUG );
@@ -1133,6 +1121,14 @@ struct dlq_item_s *dlq_remove (void)
1133
1121
if (queue_head != NULL ) {
1134
1122
result = queue_head ;
1135
1123
queue_head = queue_head -> nextp ;
1124
+ queue_length -- ;
1125
+ if (queue_head == NULL ) {
1126
+ assert (queue_length == 0 );
1127
+ queue_tail = NULL ;
1128
+ }
1129
+ if (queue_length == 1 ) {
1130
+ assert (queue_head == queue_tail );
1131
+ }
1136
1132
}
1137
1133
1138
1134
#if __WIN32__
0 commit comments