Skip to content

Commit 0338e90

Browse files
committed
Simplify queueing and locking
1 parent 2260df1 commit 0338e90

File tree

1 file changed

+58
-69
lines changed

1 file changed

+58
-69
lines changed

src/dlq.c

+58-69
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);
@@ -258,7 +252,7 @@ void dlq_rec_frame (int chan, int subchan, int slice, packet_t pp, alevel_t alev
258252

259253
/* Allocate a new queue item. */
260254

261-
pnew = (struct dlq_item_s *) calloc (sizeof(struct dlq_item_s), 1);
255+
pnew = (struct dlq_item_s *) malloc (sizeof(struct dlq_item_s));
262256
if (pnew == NULL) {
263257
text_color_set(DW_COLOR_ERROR);
264258
dw_printf ("FATAL ERROR: Out of memory.\n");
@@ -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,16 @@ static void append_to_queue (struct dlq_item_s *pnew)
341332
#endif
342333

343334
if (queue_head == NULL) {
344-
queue_head = pnew;
335+
queue_head = queue_tail = pnew;
345336
queue_length = 1;
337+
} else {
338+
queue_tail->nextp = pnew;
339+
queue_tail = pnew;
340+
queue_length++;
346341
}
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-
357342

358343
#if __WIN32__
359344
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-
}
368345
#endif
369346
#if DEBUG1
370347
text_color_set(DW_COLOR_DEBUG);
@@ -416,7 +393,7 @@ static void append_to_queue (struct dlq_item_s *pnew)
416393
* and blocking on a write.
417394
*/
418395

419-
if (queue_length > 10) {
396+
if (queue_length > 15) {
420397
text_color_set(DW_COLOR_ERROR);
421398
dw_printf ("Received frame queue is out of control. Length=%d.\n", queue_length);
422399
dw_printf ("Reader thread is probably frozen.\n");
@@ -431,29 +408,21 @@ static void append_to_queue (struct dlq_item_s *pnew)
431408
#else
432409
if (recv_thread_is_waiting) {
433410

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-
442411
err = pthread_cond_signal (&wake_up_cond);
443412
if (err != 0) {
444413
text_color_set(DW_COLOR_ERROR);
445414
dw_printf ("dlq append_to_queue: pthread_cond_signal err=%d", err);
446415
perror ("");
447416
exit (1);
448417
}
418+
}
449419

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-
}
420+
err = pthread_mutex_unlock (&dlq_mutex);
421+
if (err != 0) {
422+
text_color_set(DW_COLOR_ERROR);
423+
dw_printf ("dlq append_to_queue: pthread_mutex_unlock wu err=%d", err);
424+
perror ("");
425+
exit (1);
457426
}
458427
#endif
459428

@@ -1011,9 +980,29 @@ int dlq_wait_while_empty (double timeout)
1011980
dlq_init ();
1012981
}
1013982

983+
#if DEBUG1
984+
text_color_set(DW_COLOR_DEBUG);
985+
dw_printf ("dlq dlq_wait_while_empty: enter critical section\n");
986+
#endif
987+
#if __WIN32__
988+
EnterCriticalSection (&dlq_cs);
989+
#else
990+
int err;
991+
err = pthread_mutex_lock (&dlq_mutex);
992+
if (err != 0) {
993+
text_color_set(DW_COLOR_ERROR);
994+
dw_printf ("dlq append_to_queue: pthread_mutex_lock err=%d", err);
995+
perror ("");
996+
exit (1);
997+
}
998+
#endif
1014999

10151000
if (queue_head == NULL) {
10161001

1002+
#if __WIN32__
1003+
LeaveCriticalSection (&dlq_cs);
1004+
#endif
1005+
10171006
#if DEBUG
10181007
text_color_set(DW_COLOR_DEBUG);
10191008
dw_printf ("dlq_wait_while_empty (): prepare to SLEEP...\n");
@@ -1037,45 +1026,41 @@ int dlq_wait_while_empty (double timeout)
10371026
else {
10381027
WaitForSingleObject (wake_up_event, INFINITE);
10391028
}
1029+
} else {
1030+
#if __WIN32__
1031+
LeaveCriticalSection (&dlq_cs);
1032+
#endif
1033+
}
10401034

10411035
#else
10421036
int err;
10431037

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-
10521038
recv_thread_is_waiting = 1;
10531039
if (timeout != 0.0) {
10541040
struct timespec abstime;
10551041

10561042
abstime.tv_sec = (time_t)(long)timeout;
10571043
abstime.tv_nsec = (long)((timeout - (long)abstime.tv_sec) * 1000000000.0);
10581044

1059-
err = pthread_cond_timedwait (&wake_up_cond, &wake_up_mutex, &abstime);
1045+
err = pthread_cond_timedwait (&wake_up_cond, &dlq_mutex, &abstime);
10601046
if (err == ETIMEDOUT) {
10611047
timed_out_result = 1;
10621048
}
10631049
}
10641050
else {
1065-
err = pthread_cond_wait (&wake_up_cond, &wake_up_mutex);
1051+
err = pthread_cond_wait (&wake_up_cond, &dlq_mutex);
10661052
}
10671053
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
10771054
}
10781055

1056+
err = pthread_mutex_unlock (&dlq_mutex);
1057+
if (err != 0) {
1058+
text_color_set(DW_COLOR_ERROR);
1059+
dw_printf ("dlq_wait_while_empty: pthread_mutex_unlock wu err=%d", err);
1060+
perror ("");
1061+
exit (1);
1062+
}
1063+
#endif
10791064

10801065
#if DEBUG
10811066
text_color_set(DW_COLOR_DEBUG);
@@ -1105,7 +1090,6 @@ struct dlq_item_s *dlq_remove (void)
11051090
{
11061091

11071092
struct dlq_item_s *result = NULL;
1108-
//int err;
11091093

11101094
#if DEBUG1
11111095
text_color_set(DW_COLOR_DEBUG);
@@ -1133,6 +1117,11 @@ struct dlq_item_s *dlq_remove (void)
11331117
if (queue_head != NULL) {
11341118
result = queue_head;
11351119
queue_head = queue_head->nextp;
1120+
queue_length--;
1121+
1122+
if (queue_head == NULL) {
1123+
queue_tail = NULL;
1124+
}
11361125
}
11371126

11381127
#if __WIN32__

0 commit comments

Comments
 (0)