1
0
mirror of https://github.com/SuperBFG7/ympd synced 2025-07-06 20:02:51 +00:00

Fix: mutex error checking

This commit is contained in:
jcorporation 2019-01-20 20:03:51 +01:00
parent b0a2df9ea3
commit 044456cbba
4 changed files with 68 additions and 51 deletions

View File

@ -222,15 +222,9 @@ static void mpd_client_api(t_config *config, t_mpd_state *mpd_state, void *arg_r
float float_buf; float float_buf;
bool bool_buf, rc; bool bool_buf, rc;
char *p_charbuf1, *p_charbuf2, *p_charbuf3, *p_charbuf4; char *p_charbuf1, *p_charbuf2, *p_charbuf3, *p_charbuf4;
#ifdef DEBUG
struct timespec start, end;
#endif
LOG_VERBOSE() printf("API request (%ld): %.*s\n", request->conn_id, request->length, request->data); LOG_VERBOSE() printf("API request (%ld): %.*s\n", request->conn_id, request->length, request->data);
#ifdef DEBUG
clock_gettime(CLOCK_MONOTONIC_RAW, &start);
#endif
switch(request->cmd_id) { switch(request->cmd_id) {
case MPD_API_LIKE: case MPD_API_LIKE:
if (mpd_state->feat_sticker) { if (mpd_state->feat_sticker) {
@ -878,16 +872,6 @@ static void mpd_client_api(t_config *config, t_mpd_state *mpd_state, void *arg_r
mpd_state->conn_state = MPD_FAILURE; mpd_state->conn_state = MPD_FAILURE;
} }
#ifdef DEBUG
clock_gettime(CLOCK_MONOTONIC_RAW, &end);
uint64_t delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000;
#ifdef PKGARCH44
fprintf(stderr, "DEBUG: Time used: %lu\n", delta_us);
#else
fprintf(stderr, "DEBUG: Time used: %llu\n", delta_us);
#endif
#endif
if (len == 0) { if (len == 0) {
len = snprintf(buffer, MAX_SIZE, "{\"type\": \"error\", \"data\": \"No response for cmd_id %u.\"}", request->cmd_id); len = snprintf(buffer, MAX_SIZE, "{\"type\": \"error\", \"data\": \"No response for cmd_id %u.\"}", request->cmd_id);
} }
@ -1185,7 +1169,7 @@ static void mpd_client_idle(t_config *config, t_mpd_state *mpd_state) {
if (mpd_client_queue_length > 0) { if (mpd_client_queue_length > 0) {
//Handle request //Handle request
LOG_DEBUG() fprintf(stderr, "DEBUG: Handle request.\n"); LOG_DEBUG() fprintf(stderr, "DEBUG: Handle request.\n");
struct work_request_t *request = tiny_queue_shift(mpd_client_queue, 100); struct work_request_t *request = tiny_queue_shift(mpd_client_queue, 50);
if (request != NULL) { if (request != NULL) {
mpd_client_api(config, mpd_state, request); mpd_client_api(config, mpd_state, request);
} }

View File

@ -100,7 +100,7 @@ void *mympd_api_loop(void *arg_config) {
} }
while (s_signal_received == 0) { while (s_signal_received == 0) {
struct t_work_request *request = tiny_queue_shift(mympd_api_queue, 0); struct t_work_request *request = tiny_queue_shift(mympd_api_queue, 100);
if (request != NULL) { if (request != NULL) {
mympd_api(config, &mympd_state, request); mympd_api(config, &mympd_state, request);
} }

View File

@ -19,6 +19,7 @@
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h>
#include <stdbool.h> #include <stdbool.h>
#include <pthread.h> #include <pthread.h>
#include <asm/errno.h> #include <asm/errno.h>
@ -47,8 +48,12 @@ void tiny_queue_free(tiny_queue_t *queue) {
} }
void tiny_queue_push(tiny_queue_t *queue, void *data) { int tiny_queue_push(tiny_queue_t *queue, void *data) {
pthread_mutex_lock(&queue->mutex); int rc = pthread_mutex_lock(&queue->mutex);
if (rc != 0) {
printf("Error in pthread_mutex_lock: %d\n", rc);
return 0;
}
struct tiny_msg_t* new_node = (struct tiny_msg_t*)malloc(sizeof(struct tiny_msg_t)); struct tiny_msg_t* new_node = (struct tiny_msg_t*)malloc(sizeof(struct tiny_msg_t));
new_node->data = data; new_node->data = data;
new_node->next = NULL; new_node->next = NULL;
@ -60,53 +65,78 @@ void tiny_queue_push(tiny_queue_t *queue, void *data) {
queue->tail->next = new_node; queue->tail->next = new_node;
queue->tail = new_node; queue->tail = new_node;
} }
pthread_mutex_unlock(&queue->mutex); rc = pthread_mutex_unlock(&queue->mutex);
pthread_cond_signal(&queue->wakeup); if (rc != 0) {
printf("Error in pthread_mutex_unlock: %d\n", rc);
return 0;
}
rc = pthread_cond_signal(&queue->wakeup);
if (rc != 0) {
printf("Error in pthread_cond_signal: %d\n", rc);
return 0;
}
return 1;
} }
int tiny_queue_length(tiny_queue_t *queue, int timeout) { int tiny_queue_length(tiny_queue_t *queue, int timeout) {
pthread_mutex_lock(&queue->mutex); int rc = pthread_mutex_lock(&queue->mutex);
if (timeout > 0) { if (rc != 0) {
printf("Error in pthread_mutex_lock: %d\n", rc);
return 0;
}
if (timeout > 0 && queue->length == 0) {
struct timespec max_wait = {0, 0}; struct timespec max_wait = {0, 0};
clock_gettime(CLOCK_REALTIME, &max_wait); clock_gettime(CLOCK_REALTIME, &max_wait);
//timeout in ms //timeout in ms
max_wait.tv_nsec += timeout * 1000; max_wait.tv_nsec += timeout * 1000;
while (queue->length == 0) { rc = pthread_cond_timedwait(&queue->wakeup, &queue->mutex, &max_wait);
// block if queue is empty if (rc != 0) {
int rc = pthread_cond_timedwait(&queue->wakeup, &queue->mutex, &max_wait); printf("Error in pthread_cond_timedwait: %d\n", rc);
if (rc == ETIMEDOUT) {
break;
}
} }
} }
unsigned len = queue->length; unsigned len = queue->length;
pthread_mutex_unlock(&queue->mutex); rc = pthread_mutex_unlock(&queue->mutex);
if (rc != 0) {
printf("Error in pthread_mutex_unlock: %d\n", rc);
}
return len; return len;
} }
void *tiny_queue_shift(tiny_queue_t *queue, int timeout) { void *tiny_queue_shift(tiny_queue_t *queue, int timeout) {
pthread_mutex_lock(&queue->mutex); int rc = pthread_mutex_lock(&queue->mutex);
if (timeout > 0) { if (rc != 0) {
struct timespec max_wait = {0, 0}; printf("Error in pthread_mutex_lock: %d\n", rc);
clock_gettime(CLOCK_REALTIME, &max_wait); return 0;
//timeout in ms }
max_wait.tv_nsec += timeout * 1000; if (queue->length == 0) {
while (queue->head == NULL) { if (timeout > 0) {
// block if buffer is empty struct timespec max_wait = {0, 0};
int rc = pthread_cond_timedwait(&queue->wakeup, &queue->mutex, &max_wait); clock_gettime(CLOCK_REALTIME, &max_wait);
if (rc == ETIMEDOUT) { //timeout in ms
pthread_mutex_unlock(&queue->mutex); max_wait.tv_nsec += timeout * 1000;
rc = pthread_cond_timedwait(&queue->wakeup, &queue->mutex, &max_wait);
if (rc != 0) {
printf("Error in pthread_cond_timedwait: %d\n", rc);
rc = pthread_mutex_unlock(&queue->mutex);
if (rc != 0) {
printf("Error in pthread_mutex_unlock: %d\n", rc);
}
return NULL;
}
}
else {
rc = pthread_cond_wait(&queue->wakeup, &queue->mutex);
if (rc != 0) {
printf("Error in pthread_cond_wait: %d\n", rc);
rc = pthread_mutex_unlock(&queue->mutex);
if (rc != 0) {
printf("Error in pthread_mutex_unlock: %d\n", rc);
}
return NULL; return NULL;
} }
} }
} }
else { //queue has entry
while (queue->head == NULL) {
// block if buffer is empty
pthread_cond_wait(&queue->wakeup, &queue->mutex);
}
}
struct tiny_msg_t* current_head = queue->head; struct tiny_msg_t* current_head = queue->head;
void *data = current_head->data; void *data = current_head->data;
if (queue->head == queue->tail) { if (queue->head == queue->tail) {
@ -117,6 +147,9 @@ void *tiny_queue_shift(tiny_queue_t *queue, int timeout) {
} }
free(current_head); free(current_head);
queue->length--; queue->length--;
pthread_mutex_unlock(&queue->mutex); rc = pthread_mutex_unlock(&queue->mutex);
if (rc != 0) {
printf("Error in pthread_mutex_unlock: %d\n", rc);
}
return data; return data;
} }

View File

@ -35,7 +35,7 @@ typedef struct tiny_queue_t {
tiny_queue_t *tiny_queue_create(void); tiny_queue_t *tiny_queue_create(void);
void tiny_queue_free(tiny_queue_t *queue); void tiny_queue_free(tiny_queue_t *queue);
void tiny_queue_push(struct tiny_queue_t *queue, void *data); int tiny_queue_push(struct tiny_queue_t *queue, void *data);
void *tiny_queue_shift(struct tiny_queue_t *queue, int timeout); void *tiny_queue_shift(struct tiny_queue_t *queue, int timeout);
int tiny_queue_length(struct tiny_queue_t *queue, int timeout); int tiny_queue_length(struct tiny_queue_t *queue, int timeout);
#endif #endif