From 0f6502bf9b685d6a56f17387eacbea5c9dc0efdf Mon Sep 17 00:00:00 2001 From: Klagarge Date: Sun, 7 Jun 2026 15:11:13 +0200 Subject: [PATCH] fix(MP/daemon): add mutex on gpio --- src/06-mini-project/daemon/gpio/button.c | 10 +++++++++- src/06-mini-project/daemon/gpio/button.h | 3 +++ src/06-mini-project/daemon/gpio/led.c | 9 +++++++++ src/06-mini-project/daemon/gpio/led.h | 3 +++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/06-mini-project/daemon/gpio/button.c b/src/06-mini-project/daemon/gpio/button.c index 3cb82fa..587adf1 100644 --- a/src/06-mini-project/daemon/gpio/button.c +++ b/src/06-mini-project/daemon/gpio/button.c @@ -18,6 +18,8 @@ #define MAX_BTN 10 BTN* btn_list[MAX_BTN]; +pthread_mutex_t btn_list_mutex = PTHREAD_MUTEX_INITIALIZER; + int epoll_fd; struct epoll_event ev[MAX_BTN]; atomic_int btn_tail = 0; @@ -30,6 +32,8 @@ static void* epoll_thread(void* arg); BTN* BTN_init(BTN_type type) { BTN* btn = malloc(sizeof(BTN)); if (btn == NULL) return NULL; + pthread_mutex_init(&btn->mutex, NULL); + btn->callback = NULL; char gpio_path[32] = GPIO_BTN_BASE; switch (type) { @@ -87,8 +91,10 @@ BTN* BTN_init(BTN_type type) { char buf[2]; pread(btn->fd, buf, sizeof(buf), 0); + pthread_mutex_lock(&btn_list_mutex); int tail = atomic_fetch_add(&btn_tail, 1); if (tail >= MAX_BTN) { + pthread_mutex_unlock(&btn_list_mutex); perror("Failed to add epoll event"); exit(EXIT_FAILURE); } @@ -98,15 +104,17 @@ BTN* BTN_init(BTN_type type) { epoll_init(); } BTN_add_epoll_event(btn, tail); + pthread_mutex_unlock(&btn_list_mutex); return btn; } void BTN_set_callback(BTN* btn, BTN_callback callback) { + pthread_mutex_lock(&btn->mutex); btn->callback = callback; + pthread_mutex_unlock(&btn->mutex); } -// TODO add mutex to protect this function void BTN_add_epoll_event(BTN* btn, int tail) { // EPOLLIN is working well as EPOLLPRI (which is more used for priority data) diff --git a/src/06-mini-project/daemon/gpio/button.h b/src/06-mini-project/daemon/gpio/button.h index 2c281f3..6778b42 100644 --- a/src/06-mini-project/daemon/gpio/button.h +++ b/src/06-mini-project/daemon/gpio/button.h @@ -1,6 +1,8 @@ #ifndef BUTTON_H #define BUTTON_H +#include + #define GPIO_BTN_INCREASE "3" #define GPIO_BTN_DECREASE "0" #define GPIO_BTN_MODE "2" @@ -17,6 +19,7 @@ typedef struct { int fd; char pin[32]; BTN_callback callback; + pthread_mutex_t mutex; } BTN; BTN* BTN_init(BTN_type type); diff --git a/src/06-mini-project/daemon/gpio/led.c b/src/06-mini-project/daemon/gpio/led.c index b0e580c..7b797eb 100644 --- a/src/06-mini-project/daemon/gpio/led.c +++ b/src/06-mini-project/daemon/gpio/led.c @@ -67,6 +67,10 @@ LED* LED_init(LED_type type) { } led->gpio = f; + if (pthread_mutex_init(&led->mutex, NULL) != 0) { + close(f); + return NULL; + } return led; } @@ -74,20 +78,25 @@ void LED_on(LED* led) { if (led == NULL) { return; } + pthread_mutex_lock(&led->mutex); pwrite(led->gpio, "1", sizeof("1"), 0); + pthread_mutex_unlock(&led->mutex); } void LED_off(LED* led) { if (led == NULL) { return; } + pthread_mutex_lock(&led->mutex); pwrite(led->gpio, "0", sizeof("0"), 0); + pthread_mutex_unlock(&led->mutex); } void LED_toggle(LED* led) { if (led == NULL) { return; } + pthread_mutex_lock(&led->mutex); char value[2]; pread(led->gpio, value, sizeof(value), 0); if (value[0] == '0') { diff --git a/src/06-mini-project/daemon/gpio/led.h b/src/06-mini-project/daemon/gpio/led.h index 6b009a2..9f31acd 100644 --- a/src/06-mini-project/daemon/gpio/led.h +++ b/src/06-mini-project/daemon/gpio/led.h @@ -1,6 +1,8 @@ #ifndef LED_H #define LED_H +#include + #define GPIO_LED_STATUS "10" #define GPIO_LED_POWER "362" @@ -11,6 +13,7 @@ typedef enum { typedef struct { int gpio; + pthread_mutex_t mutex; } LED; LED* LED_init(LED_type type);