X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=select.c;h=d9baf65ac446e3a6498a469a101017389710f2ad;hb=3836bf240e627ff6ac4ad69f506c6b4fd4fb079c;hp=dde83a38279a84bacbe78e5c6aa17350c7eeac05;hpb=6b280803f0ab95a0bad13f92bb868726f4b085cb;p=ir-tcl-moved-to-github.git diff --git a/select.c b/select.c index dde83a3..d9baf65 100644 --- a/select.c +++ b/select.c @@ -1,11 +1,28 @@ /* * IR toolkit for tcl/tk - * (c) Index Data 1996 + * (c) Index Data 1996-1999 * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * * $Log: select.c,v $ - * Revision 1.2 1996-09-13 10:51:48 adam + * Revision 1.7 1999-11-30 14:05:58 adam + * Updated for new location of YAZ headers. + * + * Revision 1.6 1999/02/11 11:30:13 adam + * Updated for WIN32. + * + * Revision 1.5 1997/09/09 10:19:55 adam + * New MSV5.0 port with fewer warnings. + * + * Revision 1.4 1997/08/28 20:20:48 adam + * Added support for Tk8.0/Tcl8.0. Since Tcl_File handlers are gone + * we've moved to Tcl_Channel handlers instead. + * + * Revision 1.3 1997/04/13 18:57:28 adam + * Better error reporting and aligned with Tcl/Tk style. + * Rework of notifier code with Tcl_File handles. + * + * Revision 1.2 1996/09/13 10:51:48 adam * Bug fix: ir_tcl_select_set called Tcl_GetFile at disconnect. * * Revision 1.1 1996/08/20 09:33:23 adam @@ -14,40 +31,28 @@ */ #include -#include +#include #include "ir-tcl.h" -#if TCL_MAJOR_VERSION > 7 || (TCL_MAJOR_VERSION == 7 && TCL_MINOR_VERSION > 4) - -#define IRTCL_USE_TIMER 0 - +#if TCL_MAJOR_VERSION == 8 struct sel_proc { void (*f)(ClientData clientData, int r, int w, int e); ClientData clientData; int fd; -#if IRTCL_USE_TIMER - int mask; - Tcl_TimerToken timer_token; -#else - Tcl_File tcl_File; -#endif + Tcl_Channel tcl_Channel; struct sel_proc *next; }; static struct sel_proc *sel_proc_list = NULL; -#if IRTCL_USE_TIMER -static void ir_tcl_timer_proc (ClientData clientData) +static void ir_tcl_tk_select_proc (ClientData clientData, int mask) { struct sel_proc *sp = (struct sel_proc *) clientData; if (!sp->f) return ; - sp->timer_token = - Tcl_CreateTimerHandler (250, ir_tcl_timer_proc, clientData); - (*sp->f)(sp->clientData, sp->mask & TCL_READABLE, sp->mask & TCL_WRITABLE, - sp->mask & TCL_EXCEPTION); - + (*sp->f)(sp->clientData, mask & TCL_READABLE, mask & TCL_WRITABLE, + mask & TCL_EXCEPTION); } void ir_tcl_select_set (void (*f)(ClientData clientData, int r, int w, int e), @@ -65,32 +70,49 @@ void ir_tcl_select_set (void (*f)(ClientData clientData, int r, int w, int e), while (*sp) { if ((*sp)->fd == fd) - break; + break; sp = &(*sp)->next; } + logf (LOG_DEBUG, "r=%d w=%d e=%d sp=%p", r, w, e, *sp); + if (*sp) + Tcl_DeleteChannelHandler ((*sp)->tcl_Channel, ir_tcl_tk_select_proc, + (*sp)->clientData); + if (!f) + { + if (*sp) + { + Tcl_Close (NULL, (*sp)->tcl_Channel); + *sp = (*sp)->next; + } + return ; + } if (!*sp) { - if (!f) - return; *sp = ir_tcl_malloc (sizeof(**sp)); (*sp)->next = NULL; (*sp)->fd = fd; - (*sp)->timer_token = - Tcl_CreateTimerHandler (250, ir_tcl_timer_proc, *sp); + (*sp)->tcl_Channel = Tcl_MakeTcpClientChannel ((ClientData) fd); } - (*sp)->mask = TCL_READABLE|TCL_WRITABLE; (*sp)->f = f; (*sp)->clientData = clientData; - if (!f) - { - struct sel_proc *sp_tmp = *sp; - Tcl_DeleteTimerHandler ((*sp)->timer_token); - *sp = (*sp)->next; - xfree (sp_tmp); - } + Tcl_CreateChannelHandler ((*sp)->tcl_Channel, mask, + ir_tcl_tk_select_proc, + (ClientData) *sp); } +#endif + +#if (TCL_MAJOR_VERSION == 7 && TCL_MINOR_VERSION > 4) + +struct sel_proc { + void (*f)(ClientData clientData, int r, int w, int e); + ClientData clientData; + int fd; + Tcl_File tcl_File; + struct sel_proc *next; +}; + +static struct sel_proc *sel_proc_list = NULL; -#else static void ir_tcl_tk_select_proc (ClientData clientData, int mask) { struct sel_proc *sp = (struct sel_proc *) clientData; @@ -105,7 +127,7 @@ void ir_tcl_select_set (void (*f)(ClientData clientData, int r, int w, int e), int fd, ClientData clientData, int r, int w, int e) { int mask = 0; - struct sel_proc *sp = sel_proc_list; + struct sel_proc **sp = &sel_proc_list; if (r) mask |= TCL_READABLE; @@ -113,33 +135,37 @@ void ir_tcl_select_set (void (*f)(ClientData clientData, int r, int w, int e), mask |= TCL_WRITABLE; if (e) mask |= TCL_EXCEPTION; - while (sp) + while (*sp) { - if (sp->fd == fd) + if ((*sp)->fd == fd) break; - sp = sp->next; + sp = &(*sp)->next; + } + logf (LOG_DEBUG, "r=%d w=%d e=%d sp=%p", r, w, e, *sp); + if (!f) + { + if (*sp) + { + Tcl_DeleteFileHandler ((*sp)->tcl_File); + Tcl_FreeFile ((*sp)->tcl_File); + *sp = (*sp)->next; + } + return ; } - if (!sp) + if (!*sp) { - if (!f) - return; - sp = ir_tcl_malloc (sizeof(*sp)); - sp->next = sel_proc_list; - sel_proc_list = sp; - sp->fd = fd; -#if WINDOWS - sp->tcl_File = Tcl_GetFile ((ClientData) fd, TCL_WIN_SOCKET); + *sp = ir_tcl_malloc (sizeof(**sp)); + (*sp)->next = NULL; + (*sp)->fd = fd; +#if WIN32 + (*sp)->tcl_File = Tcl_GetFile ((ClientData) fd, TCL_WIN_SOCKET); #else - sp->tcl_File = Tcl_GetFile ((ClientData) fd, TCL_UNIX_FD); + (*sp)->tcl_File = Tcl_GetFile ((ClientData) fd, TCL_UNIX_FD); #endif } - sp->f = f; - sp->clientData = clientData; - if (f) - Tcl_CreateFileHandler (sp->tcl_File, mask, ir_tcl_tk_select_proc, sp); - else - Tcl_DeleteFileHandler (sp->tcl_File); + (*sp)->f = f; + (*sp)->clientData = clientData; + Tcl_CreateFileHandler ((*sp)->tcl_File, mask, ir_tcl_tk_select_proc, *sp); } #endif -#endif