diff options
| author | Bill Spitzak <spitzak@gmail.com> | 1999-04-17 01:02:30 +0000 |
|---|---|---|
| committer | Bill Spitzak <spitzak@gmail.com> | 1999-04-17 01:02:30 +0000 |
| commit | 0e29799dda01961603e5dbd790681b0e0303f485 (patch) | |
| tree | 39a464e73d39a660f5b7a93ee85340115dbd8b93 /src | |
| parent | 677604187378f4d3a85433963f97c4de34eea659 (diff) | |
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
Diffstat (limited to 'src')
| -rw-r--r-- | src/Fl.cxx | 53 | ||||
| -rw-r--r-- | src/Fl_win32.cxx | 106 | ||||
| -rw-r--r-- | src/Fl_x.cxx | 102 |
3 files changed, 152 insertions, 109 deletions
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 <FL/Fl_Window.H> #include <FL/x.H> #include <ctype.h> +#include <malloc.h> +#include <string.h> // // 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<MAXTIMEOUT) numtimeouts++; - for (i=0; i<(numtimeouts-1); i++) { + 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<numtimeouts; i++) { if (timeout[i].time > 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<numtimeouts && timeout[j].time <= 0; i++,j++) { - temp[i].cb = timeout[j].cb; - temp[i].arg= timeout[j].arg; + while (numtimeouts) { + if (timeout[0].time > 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<numtimeouts;) timeout[k++] = timeout[j++]; - numtimeouts = k; - // and then call them: - for (k=0; k<i; k++) temp[k].cb(temp[k].arg); } void Fl::flush() { @@ -695,5 +696,5 @@ int fl_old_shortcut(const char* s) { } // -// End of "$Id: Fl.cxx,v 1.24.2.3 1999/04/10 08:09:38 bill Exp $". +// End of "$Id: Fl.cxx,v 1.24.2.4 1999/04/17 01:02:28 bill Exp $". // diff --git a/src/Fl_win32.cxx b/src/Fl_win32.cxx index 8f424b701..a687cd448 100644 --- a/src/Fl_win32.cxx +++ b/src/Fl_win32.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_win32.cxx,v 1.33.2.5 1999/04/10 08:09:38 bill Exp $" +// "$Id: Fl_win32.cxx,v 1.33.2.6 1999/04/17 01:02:29 bill Exp $" // // WIN32-specific code for the Fast Light Tool Kit (FLTK). // @@ -56,43 +56,60 @@ #define POLLIN 1 #define POLLOUT 4 #define POLLERR 8 -struct pollfd {int fd; short events; short revents;}; -#define MAXFD 8 -static fd_set fdsets[3]; -static int nfds; -static struct pollfd fds[MAXFD]; -static struct { +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;} - fds[i].fd = n; - fds[i].events = events; + 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)); + } + 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<nfds; i++) { - if (fds[i].fd == n); - else {if (j<i) {fd[j]=fd[i]; fds[j]=fds[i];} j++;} + if (fd[i].fd == n) { + int e = fd[i].events & ~events; + if (!e) continue; // if no events left, delete this fd + fd[i].events = e; + } + // move it down in the array if necessary: + if (j<i) { + fd[j]=fd[i]; + } + j++; } nfds = j; - FD_CLR(n, &fdsets[0]); - FD_CLR(n, &fdsets[1]); - FD_CLR(n, &fdsets[2]); + if (events & POLLIN) FD_CLR(n, &fdsets[0]); + if (events & POLLOUT) FD_CLR(n, &fdsets[1]); + if (events & POLLERR) FD_CLR(n, &fdsets[2]); + if (n == maxfd) maxfd--; +} + +void Fl::remove_fd(int n) { + remove_fd(n, -1); } MSG fl_msg; @@ -112,29 +129,28 @@ int fl_ready() { double fl_wait(int timeout_flag, double time) { int have_message; - timeval t; - fd_set fdt[3]; - - - // For WIN32 we need to poll for socket input FIRST, since - // the event queue is not something we can select() on... - - t.tv_sec = 0; - t.tv_usec = 0; - - fdt[0] = fdsets[0]; - fdt[1] = fdsets[1]; - fdt[2] = fdsets[2]; - - if (::select(0,&fdt[0],&fdt[1],&fdt[2],&t)) { - // We got something - do the callback! - for (int i = 0; i < nfds; i ++) { - int f = fds[i].fd; - short revents = 0; - if (FD_ISSET(f,&fdt[0])) revents |= POLLIN; - if (FD_ISSET(f,&fdt[1])) revents |= POLLOUT; - if (FD_ISSET(f,&fdt[2])) revents |= POLLERR; - if (fds[i].events & revents) fd[i].cb(f, fd[i].arg); + if (nfds) { + // For WIN32 we need to poll for socket input FIRST, since + // the event queue is not something we can select() on... + timeval t; + t.tv_sec = 0; + t.tv_usec = 0; + + fd_set fdt[3]; + fdt[0] = fdsets[0]; + fdt[1] = fdsets[1]; + fdt[2] = fdsets[2]; + + if (::select(0,&fdt[0],&fdt[1],&fdt[2],&t)) { + // We got something - do the callback! + for (int i = 0; i < nfds; i ++) { + int f = fd[i].fd; + short revents = 0; + if (FD_ISSET(f,&fdt[0])) revents |= POLLIN; + if (FD_ISSET(f,&fdt[1])) revents |= POLLOUT; + if (FD_ISSET(f,&fdt[2])) revents |= POLLERR; + if (fd[i].events & revents) fd[i].cb(f, fd[i].arg); + } } } @@ -905,5 +921,5 @@ void Fl_Window::make_current() { } // -// End of "$Id: Fl_win32.cxx,v 1.33.2.5 1999/04/10 08:09:38 bill Exp $". +// End of "$Id: Fl_win32.cxx,v 1.33.2.6 1999/04/17 01:02:29 bill Exp $". // diff --git a/src/Fl_x.cxx b/src/Fl_x.cxx index 96f264646..02b0a458a 100644 --- a/src/Fl_x.cxx +++ b/src/Fl_x.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_x.cxx,v 1.24.2.2 1999/04/10 08:09:39 bill Exp $" +// "$Id: Fl_x.cxx,v 1.24.2.3 1999/04/17 01:02:29 bill Exp $" // // X specific code for the Fast Light Tool Kit (FLTK). // @@ -41,77 +41,103 @@ #include <string.h> #include <unistd.h> #include <sys/time.h> -#if HAVE_SYS_SELECT_H -# include <sys/select.h> -#endif /* HAVE_SYS_SELECT_H */ //////////////////////////////////////////////////////////////// // interface to poll/select call: #if HAVE_POLL + #include <poll.h> +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 <sys/select.h> +#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<nfds; i++) { - if (fds[i].fd == n); - else {if (j<i) {fd[j]=fd[i]; fds[j]=fds[i];} j++;} + if (fd[i].fd == n) { + int e = fd[i].events & ~events; + if (!e) continue; // if no events left, delete this fd + fd[i].events = e; +#if HAVE_POLL + fds[j].events = e; +#endif + } + // move it down in the array if necessary: + if (j<i) { + fd[j]=fd[i]; +#if HAVE_POLL + fds[j]=fds[i]; +#endif + } + j++; } nfds = j; #if !HAVE_POLL - FD_CLR(n, &fdsets[0]); - FD_CLR(n, &fdsets[1]); - FD_CLR(n, &fdsets[2]); + if (events & POLLIN) FD_CLR(n, &fdsets[0]); + if (events & POLLOUT) FD_CLR(n, &fdsets[1]); + if (events & POLLERR) FD_CLR(n, &fdsets[2]); if (n == maxfd) maxfd--; #endif } +void Fl::remove_fd(int n) { + remove_fd(n, -1); +} + int fl_ready() { if (XQLength(fl_display)) return 1; #if HAVE_POLL @@ -185,14 +211,14 @@ double fl_wait(int timeout_flag, double time) { if (n > 0) { for (int i=0; i<nfds; i++) { #if HAVE_POLL - if (fds[i].revents) fd[i].cb(fds[i].fd, fd[i].arg); + if (fds[i].revents) fd[i].cb(fd[i].fd, fd[i].arg); #else - int f = fds[i].fd; + int f = fd[i].fd; short revents = 0; if (FD_ISSET(f,&fdt[0])) revents |= POLLIN; if (FD_ISSET(f,&fdt[1])) revents |= POLLOUT; if (FD_ISSET(f,&fdt[2])) revents |= POLLERR; - if (fds[i].events & revents) fd[i].cb(f, fd[i].arg); + if (fd[i].events & revents) fd[i].cb(f, fd[i].arg); #endif } } @@ -823,5 +849,5 @@ void Fl_Window::make_current() { #endif // -// End of "$Id: Fl_x.cxx,v 1.24.2.2 1999/04/10 08:09:39 bill Exp $". +// End of "$Id: Fl_x.cxx,v 1.24.2.3 1999/04/17 01:02:29 bill Exp $". // |
