From 0e29799dda01961603e5dbd790681b0e0303f485 Mon Sep 17 00:00:00 2001 From: Bill Spitzak Date: Sat, 17 Apr 1999 01:02:30 +0000 Subject: Fl::add_fd() structures are dynamically allocated so you can listen to as many connections as you want (up to the maximum number handled by select()). Fl::remove_fd(fd, when) added. This allows you to remove the read, write, and error callbacks individually. Fl::remove_fd(fd) does Fl::remove_fd(fd,-1). Fl::add_fd() calls Fl::remove_fd(), so it can be used safely to replace callbacks with new ones for the same file descriptor. Fl::add_timeout() also dynamically allocates it's array so there is no limit on the number of pending timeouts. I cut/pasted the changes into the Windoze version but this is UNTESTED! Somebody please do a test compile. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.0@544 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- src/Fl.cxx | 53 ++++++++++++++-------------- src/Fl_win32.cxx | 106 ++++++++++++++++++++++++++++++++----------------------- src/Fl_x.cxx | 102 ++++++++++++++++++++++++++++++++-------------------- 3 files changed, 152 insertions(+), 109 deletions(-) (limited to 'src') diff --git a/src/Fl.cxx b/src/Fl.cxx index 9b03897d1..df51ed702 100644 --- a/src/Fl.cxx +++ b/src/Fl.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl.cxx,v 1.24.2.3 1999/04/10 08:09:38 bill Exp $" +// "$Id: Fl.cxx,v 1.24.2.4 1999/04/17 01:02:28 bill Exp $" // // Main event handling code for the Fast Light Tool Kit (FLTK). // @@ -27,6 +27,8 @@ #include #include #include +#include +#include // // Globals... @@ -68,31 +70,36 @@ int Fl::event_inside(const Fl_Widget *o) /*const*/ { // Timeouts are insert-sorted into order. This works good if there // are only a small number: -#define MAXTIMEOUT 8 - -static struct { +static struct Timeout { double time; void (*cb)(void*); void* arg; -} timeout[MAXTIMEOUT+1]; +} * timeout; static int numtimeouts; +static int timeout_array_size; void Fl::add_timeout(double t, void (*cb)(void *), void *v) { - int i; fl_elapsed(); - if (numtimeouts= timeout_array_size) { + timeout_array_size = 2*timeout_array_size+1; + timeout = (Timeout*)realloc(timeout, timeout_array_size*sizeof(Timeout)); + } + + // insert-sort the new timeout: + int i; + for (i=0; i t) { - for (int j=numtimeouts-1; j>i; j--) timeout[j] = timeout[j-1]; + for (int j=numtimeouts; j>i; j--) timeout[j] = timeout[j-1]; break; } } - timeout[i].time = t; timeout[i].cb = cb; timeout[i].arg = v; + + numtimeouts++; } void Fl::remove_timeout(void (*cb)(void *), void *v) { @@ -105,22 +112,16 @@ void Fl::remove_timeout(void (*cb)(void *), void *v) { } static void call_timeouts() { - if (timeout[0].time > 0) return; - struct { - void (*cb)(void *); - void *arg; - } temp[MAXTIMEOUT]; - int i,j,k; - // copy all expired timeouts to temp array: - for (i=j=0; j 0) break; + // we must remove timeout from array before doing the callback: + void (*cb)(void*) = timeout[0].cb; + void *arg = timeout[0].arg; + numtimeouts--; + if (numtimeouts) memmove(timeout, timeout+1, numtimeouts*sizeof(Timeout)); + // now it is safe for the callback to do add_timeout: + cb(arg); } - // remove them from source array: - for (k=0; j= fd_array_size) { + fd_array_size = 2*fd_array_size+1; + fd = (FD*)realloc(fd, fd_array_size*sizeof(FD)); + } + fd[i].fd = n; + fd[i].events = events; + fd[i].cb = cb; + fd[i].arg = v; if (events & POLLIN) FD_SET(n, &fdsets[0]); if (events & POLLOUT) FD_SET(n, &fdsets[1]); if (events & POLLERR) FD_SET(n, &fdsets[2]); - fd[i].cb = cb; - fd[i].arg = v; + if (n > maxfd) maxfd = n; } void Fl::add_fd(int fd, void (*cb)(int, void*), void* v) { - Fl::add_fd(fd,POLLIN,cb,v); + Fl::add_fd(fd, POLLIN, cb, v); } -void Fl::remove_fd(int n) { +void Fl::remove_fd(int n, int events) { int i,j; for (i=j=0; i #include #include -#if HAVE_SYS_SELECT_H -# include -#endif /* HAVE_SYS_SELECT_H */ //////////////////////////////////////////////////////////////// // interface to poll/select call: #if HAVE_POLL + #include +static pollfd *pollfds = 0; + #else -struct pollfd {int fd; short events; short revents;}; -#define POLLIN 1 -#define POLLOUT 4 -#define POLLERR 8 -// -// The following #define is only needed for HP-UX 9.x and earlier. 10.x -// and beyond have the right stuff, and any good GCC distribution fixes -// this, too! -// +#if HAVE_SYS_SELECT_H +# include +#endif /* HAVE_SYS_SELECT_H */ +// The following #define is only needed for HP-UX 9.x and earlier: //#define select(a,b,c,d,e) select((a),(int *)(b),(int *)(c),(int *)(d),(e)) -#endif - -#define MAXFD 8 -#if !HAVE_POLL static fd_set fdsets[3]; static int maxfd; -#endif -static int nfds; -static struct pollfd fds[MAXFD]; -static struct { +#define POLLIN 1 +#define POLLOUT 4 +#define POLLERR 8 + +#endif /* HAVE_POLL */ + +static int nfds = 0; +static int fd_array_size = 0; +static struct FD { + int fd; + short events; void (*cb)(int, void*); void* arg; -} fd[MAXFD]; +} *fd = 0; void Fl::add_fd(int n, int events, void (*cb)(int, void*), void *v) { - int i; - if (nfds < MAXFD) {i = nfds; nfds++;} else {i = MAXFD-1;} + remove_fd(n,events); + int i = nfds++; + if (i >= fd_array_size) { + fd_array_size = 2*fd_array_size+1; + fd = (FD*)realloc(fd, fd_array_size*sizeof(FD)); +#if HAVE_POLL + pollfds = (pollfd*)realloc(pollfds, fd_array_size*sizeof(pollfd)); +#endif + } + fd[i].fd = n; + fd[i].events = events; + fd[i].cb = cb; + fd[i].arg = v; +#if HAVE_POLL fds[i].fd = n; fds[i].events = events; -#if !HAVE_POLL +#else if (events & POLLIN) FD_SET(n, &fdsets[0]); if (events & POLLOUT) FD_SET(n, &fdsets[1]); if (events & POLLERR) FD_SET(n, &fdsets[2]); if (n > maxfd) maxfd = n; #endif - fd[i].cb = cb; - fd[i].arg = v; } void Fl::add_fd(int fd, void (*cb)(int, void*), void* v) { - Fl::add_fd(fd,POLLIN,cb,v); + Fl::add_fd(fd, POLLIN, cb, v); } -void Fl::remove_fd(int n) { +void Fl::remove_fd(int n, int events) { int i,j; for (i=j=0; i 0) { for (int i=0; i