summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthias Melcher <github@matthiasm.com>2025-06-19 16:04:56 +0200
committerMatthias Melcher <github@matthiasm.com>2025-06-19 16:04:56 +0200
commit2a7b3c81c1d291f3ad42af1c780074e82988367d (patch)
treedebd05638652208d1beddf7bebe798267a5a6408 /src
parenteadea6a992d4e105b3165a22d091c66be374ae99 (diff)
Ensure that the 'awake' pipe does not overflow (#1263)
Diffstat (limited to 'src')
-rw-r--r--src/drivers/Posix/Fl_Posix_System_Driver.cxx26
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)();