joan2937 / pigpio

pigpio is a C library for the Raspberry which allows control of the General Purpose Input Outputs (GPIO).
The Unlicense
1.45k stars 407 forks source link

function callback() is not threadsafe #529

Closed roko74 closed 2 years ago

roko74 commented 2 years ago

In my current project I start four threads with similar code inside.

// start readButtonThread pthreadButtonThread = start_thread(pthreadButtonThreadFunc, &gdx);

// start readWallboxThread pthreadWallboxThread = start_thread(pthreadWallboxThreadFunc, &gdx);

// start readVeh12VThread pthreadVeh12VThread = start_thread(pthreadVeh12VThreadFunc, &gdx);

// start readVeh9VThread pthreadVeh9VThread = start_thread(pthreadVeh9VThreadFunc, &gdx);

// start readVeh6VThread pthreadVeh6VThread = start_thread(pthreadVeh6VThreadFunc, &gdx);

The functional background of these four threads is the PWM detection on four different pins. Because the code is quite identical in all four threads, the call of the callback() function ist almost at the same time. Without a critical section around the call of the function callback() the edge triggering will not initialized properly.

// Set up callback for PWM input callback(gdxlocal->nPiGpio, NO_GPIO_PWM_IN_PL_WALLBOX, EITHER_EDGE, wb_pwm_cbfunc);

With a critical section around the callback() function or speration of the thread starting functions by sleep(1) the application works without issues, so I assume that the callback() of the library is not threadsafe.

I can reproduce thise issue on a Raspberry Pi 4B and also on a Raspberry ZERO2 W. The used pigpio library is the latest in the repository of the Raspberry Pi OS repo (based on Debian bullseye).

guymcswain commented 2 years ago

so I assume that the callback() of the library is not threadsafe

... or the API called inside the callback isn't thread safe. Some, actually quite a few, APIs are not thread safe. So placing your callback in a critical section is a good solution.

roko74 commented 2 years ago

Thank you for your feedback.