X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=select.c;h=d9baf65ac446e3a6498a469a101017389710f2ad;hb=refs%2Fheads%2Fmaster;hp=93f201233af4d8f823ad98cece294085cdea0d05;hpb=1f5d222e3f2243f335e7c45f4c1a2529297ddb6c;p=ir-tcl-moved-to-github.git diff --git a/select.c b/select.c index 93f2012..d9baf65 100644 --- a/select.c +++ b/select.c @@ -1,50 +1,58 @@ /* * 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.1 1996-08-20 09:33:23 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 * Tcl7.5 Generic file handling. * */ #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), @@ -62,30 +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) { *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; @@ -100,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; @@ -108,31 +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) { - 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