diff options
| author | Matthias Melcher <github@matthiasm.com> | 2025-06-19 16:04:56 +0200 |
|---|---|---|
| committer | Matthias Melcher <github@matthiasm.com> | 2025-06-19 16:04:56 +0200 |
| commit | 2a7b3c81c1d291f3ad42af1c780074e82988367d (patch) | |
| tree | debd05638652208d1beddf7bebe798267a5a6408 | |
| parent | eadea6a992d4e105b3165a22d091c66be374ae99 (diff) | |
Ensure that the 'awake' pipe does not overflow (#1263)
| -rw-r--r-- | src/drivers/Posix/Fl_Posix_System_Driver.cxx | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/src/drivers/Posix/Fl_Posix_System_Driver.cxx b/src/drivers/Posix/Fl_Posix_System_Driver.cxx index 4b8a14d79..35d9b7703 100644 --- a/src/drivers/Posix/Fl_Posix_System_Driver.cxx +++ b/src/drivers/Posix/Fl_Posix_System_Driver.cxx @@ -321,6 +321,8 @@ int Fl_Posix_System_Driver::close_fd(int fd) { return close(fd); } # include <unistd.h> # include <fcntl.h> # include <pthread.h> +# include <sys/ioctl.h> +# include <mutex> // for std::mutex (since C++11) // Pipe for thread messaging via Fl::awake()... static int thread_filedes[2]; @@ -368,13 +370,25 @@ static void unlock_function_rec() { } # endif // HAVE_PTHREAD_MUTEX_RECURSIVE +// -- Start of "awake" implementation -- +static void* thread_message_ = nullptr; +static std::mutex pipe_mutex; + void Fl_Posix_System_Driver::awake(void* msg) { + thread_message_ = msg; if (thread_filedes[1]) { - if (write(thread_filedes[1], &msg, sizeof(void*))==0) { /* ignore */ } + pipe_mutex.lock(); + int avail = 0; + ioctl(thread_filedes[0], FIONREAD, &avail); + if (avail == 0) { + // Only write to the pipe if there is no data wainting to avoid overflow. + char dummy = 0; + if (write(thread_filedes[1], &dummy, 1)==0) { /* ignore */ } + } + pipe_mutex.unlock(); } } -static void* thread_message_; void* Fl_Posix_System_Driver::thread_message() { void* r = thread_message_; thread_message_ = 0; @@ -382,8 +396,11 @@ void* Fl_Posix_System_Driver::thread_message() { } static void thread_awake_cb(int fd, void*) { - if (read(fd, &thread_message_, sizeof(void*))==0) { - /* This should never happen */ + if (thread_filedes[1]) { + pipe_mutex.lock(); + char dummy = 0; + if (read(fd, &dummy, 1)==0) { /* This should never happen */ } + pipe_mutex.unlock(); } Fl_Awake_Handler func; void *data; @@ -391,6 +408,7 @@ static void thread_awake_cb(int fd, void*) { (*func)(data); } } +// -- End of "awake" implementation -- // These pointers are in Fl_x.cxx: extern void (*fl_lock_function)(); |
