Skip to content

Commit 3368618

Browse files
committed
Simplify queueing and locking
1 parent 5d35780 commit 3368618

File tree

1 file changed

+63
-67
lines changed

1 file changed

+63
-67
lines changed

src/dlq.c

+63-67
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@
6060
/* The queue is a linked list of these. */
6161

6262
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 */
6365

6466
#if __WIN32__
6567

@@ -75,8 +77,6 @@ static pthread_mutex_t dlq_mutex; /* Critical section for updating queues. */
7577

7678
static pthread_cond_t wake_up_cond; /* Notify received packet processing thread when queue not empty. */
7779

78-
static pthread_mutex_t wake_up_mutex; /* Required by cond_wait. */
79-
8080
static volatile int recv_thread_is_waiting = 0;
8181

8282
#endif
@@ -117,7 +117,8 @@ void dlq_init (void)
117117
dw_printf ("dlq_init ( )\n");
118118
#endif
119119

120-
queue_head = NULL;
120+
queue_head = queue_tail = NULL;
121+
queue_length = 0;
121122

122123

123124
#if DEBUG
@@ -129,13 +130,6 @@ void dlq_init (void)
129130
InitializeCriticalSection (&dlq_cs);
130131
#else
131132
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-
}
139133
err = pthread_mutex_init (&dlq_mutex, NULL);
140134
if (err != 0) {
141135
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
314308

315309
static void append_to_queue (struct dlq_item_s *pnew)
316310
{
317-
struct dlq_item_s *plast;
318-
int queue_length = 0;
319-
320311
if ( ! was_init) {
321312
dlq_init ();
322313
}
@@ -341,30 +332,19 @@ static void append_to_queue (struct dlq_item_s *pnew)
341332
#endif
342333

343334
if (queue_head == NULL) {
344-
queue_head = pnew;
335+
assert (queue_tail == NULL);
336+
queue_head = queue_tail = pnew;
345337
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);
346344
}
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-
357345

358346
#if __WIN32__
359347
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-
}
368348
#endif
369349
#if DEBUG1
370350
text_color_set(DW_COLOR_DEBUG);
@@ -416,7 +396,7 @@ static void append_to_queue (struct dlq_item_s *pnew)
416396
* and blocking on a write.
417397
*/
418398

419-
if (queue_length > 10) {
399+
if (queue_length > 15) {
420400
text_color_set(DW_COLOR_ERROR);
421401
dw_printf ("Received frame queue is out of control. Length=%d.\n", queue_length);
422402
dw_printf ("Reader thread is probably frozen.\n");
@@ -431,29 +411,21 @@ static void append_to_queue (struct dlq_item_s *pnew)
431411
#else
432412
if (recv_thread_is_waiting) {
433413

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-
442414
err = pthread_cond_signal (&wake_up_cond);
443415
if (err != 0) {
444416
text_color_set(DW_COLOR_ERROR);
445417
dw_printf ("dlq append_to_queue: pthread_cond_signal err=%d", err);
446418
perror ("");
447419
exit (1);
448420
}
421+
}
449422

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);
457429
}
458430
#endif
459431

@@ -1011,9 +983,29 @@ int dlq_wait_while_empty (double timeout)
1011983
dlq_init ();
1012984
}
1013985

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
10141002

10151003
if (queue_head == NULL) {
10161004

1005+
#if __WIN32__
1006+
LeaveCriticalSection (&dlq_cs);
1007+
#endif
1008+
10171009
#if DEBUG
10181010
text_color_set(DW_COLOR_DEBUG);
10191011
dw_printf ("dlq_wait_while_empty (): prepare to SLEEP...\n");
@@ -1037,45 +1029,41 @@ int dlq_wait_while_empty (double timeout)
10371029
else {
10381030
WaitForSingleObject (wake_up_event, INFINITE);
10391031
}
1032+
} else {
1033+
#if __WIN32__
1034+
LeaveCriticalSection (&dlq_cs);
1035+
#endif
1036+
}
10401037

10411038
#else
10421039
int err;
10431040

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-
10521041
recv_thread_is_waiting = 1;
10531042
if (timeout != 0.0) {
10541043
struct timespec abstime;
10551044

10561045
abstime.tv_sec = (time_t)(long)timeout;
10571046
abstime.tv_nsec = (long)((timeout - (long)abstime.tv_sec) * 1000000000.0);
10581047

1059-
err = pthread_cond_timedwait (&wake_up_cond, &wake_up_mutex, &abstime);
1048+
err = pthread_cond_timedwait (&wake_up_cond, &dlq_mutex, &abstime);
10601049
if (err == ETIMEDOUT) {
10611050
timed_out_result = 1;
10621051
}
10631052
}
10641053
else {
1065-
err = pthread_cond_wait (&wake_up_cond, &wake_up_mutex);
1054+
err = pthread_cond_wait (&wake_up_cond, &dlq_mutex);
10661055
}
10671056
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
10771057
}
10781058

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
10791067

10801068
#if DEBUG
10811069
text_color_set(DW_COLOR_DEBUG);
@@ -1133,6 +1121,14 @@ struct dlq_item_s *dlq_remove (void)
11331121
if (queue_head != NULL) {
11341122
result = queue_head;
11351123
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+
}
11361132
}
11371133

11381134
#if __WIN32__

0 commit comments

Comments
 (0)