📄 sbhtevtlst.cpp
字号:
/***************************************************************************** ***************************************************************************** * * $Id: SBHTEvtLst.cpp,v 1.1.2.4 2002/02/04 18:17:57 dmeyer Exp $ * * Enhanced W3C Sample Code Library libwww Persistent Cache Manager * * Enhanced to add locks in the event loop for multi-threaded SBinet. * * Original W3C Libwww notes: * * Updated HTEvent module * This new module combines the functions of the old HTEvent module and * the HTThread module. We retain the old HTThread module, but it * consists of calls to the HTEvent interfaces * * Authors: * HFN Henrik Frystyk <frystyk@w3.org> * CLB Charlie Brooks <cbrooks@osf.org> * WSAAsyncSelect and windows app stuff need the following definitions: * WWW_WIN_ASYNC - enable WSAAsyncSelect instead of select * _WIN23 - win32 libararies - may be window or console app * _WINSOCKAPI_ - using WINSOCK.DLL - not necessarily the async routines. * _CONSOLE - the console app for NT * * first pass: EGP - 10/26/95 * ***************************************************************************** ****************************************************************************//****************License************************************************ * * (c) COPYRIGHT MIT 1995. * Please first read the full copyright statement in the file COPYRIGH. * * Copyright 2000-2001. SpeechWorks International, Inc. * * Use of this software is subject to notices and obligations set forth * in the SpeechWorks Public License - Software Version 1.1 which is * included with this software. * * SpeechWorks is a registered trademark, and SpeechWorks Here, * DialogModules and the SpeechWorks logo are trademarks of SpeechWorks * International, Inc. in the United States and other countries. * ************************************************************************ *//* Implementation dependent include files */#include "wwwsys.h"#include "WWWUtil.h"#include "WWWCore.h"#include "HTReqMan.h"#include "HTTimer.h"#include "HTEvent.h"#ifdef EINVAL// Conflicts with OS definition#undef EINVAL#endif#include "SBinetChannel.h"#include "VXItrd.h"#define SBPUBLIC extern "C"#include "SBHTEvtLst.h" /* Implemented here */#ifdef WIN32/* Suppress/disable warnings */#pragma warning(4 : 4390) /* empty controlled statement found (from Libwww macros) */#pragma warning(4 : 4706) /* Assignment within conditional expression (for Libwww HTList_[...]( ) macros) */#endif/* Type definitions and global variables etc. local to this module */#define MILLI_PER_SECOND 1000#define HASH(s) ((s) % HT_M_HASH_SIZE) #define EVENTS_TO_EXECUTE 10 /* how many to execute in one select loop */#define HT_FS_BYTES(a) ((((a)/16)+1) * 4)typedef struct { SOCKET s ; /* our socket */ HTEvent * events[HTEvent_TYPES]; /* event parameters for read, write, oob */ HTTimer * timeouts[HTEvent_TYPES];} SockEvents;typedef struct { HTEvent * event; SOCKET s; HTEventType type; HTPriority skipped;} EventOrder;typedef enum { SockEvents_mayCreate, SockEvents_find} SockEvents_action;PRIVATE HTList * HashTable [HT_M_HASH_SIZE]; PRIVATE HTList * EventOrderList = NULL;PRIVATE int HTEndLoop = 0; /* If !0 then exit event loop */PRIVATE BOOL HTInLoop = NO;#ifdef WWW_WIN_ASYNC#define TIMEOUT 1 /* WM_TIMER id */PRIVATE HWND HTSocketWin;PRIVATE ATOM HTclass;PRIVATE HINSTANCE HTinstance;PRIVATE unsigned long HTwinMsg;#else /* WWW_WIN_ASYNC */PRIVATE fd_set FdArray[HTEvent_TYPES];PRIVATE SOCKET MaxSock = 0; /* max socket value in use */#endif /* !WWW_WIN_ASYNC *//* ------------------------------------------------------------------------- *//* DEBUG FUNCTIONS *//* ------------------------------------------------------------------------- */#ifdef HTDEBUGPRIVATE void Event_trace (HTEvent * event){ if (event) { HTTRACE(ALL_TRACE, "%8p: %3d %6d %8p %8p %8p" _ event _ event->priority _ event->millis _ event->cbf _ event->param _ event->request); }}PRIVATE void Event_traceHead (void){ HTTRACE(ALL_TRACE, " event: pri millis callback param request ");}PRIVATE void Timer_trace (HTTimer * timer){ if (timer) { HTTRACE(ALL_TRACE, "%8p: %6d %ld %c %8p" _ timer _ HTTimer_expiresAbsolute(timer) _ HTTimer_expiresRelative(timer) _ HTTimer_isRelative(timer) ? 'R' : 'A' _ HTTimer_callback(timer)); }}PRIVATE void Timer_traceHead (void){ HTTRACE(ALL_TRACE, " timer: millis expires ? param callback ");}/*** A simple debug function that dumps all the socket arrays** as trace messages*/PRIVATE void EventList_dump (void){ int v = 0; HTList* cur; SockEvents * pres; HTTRACE(ALL_TRACE, "Event....... Dumping socket events\n"); HTTRACE(ALL_TRACE, "soc "); Event_traceHead(); HTTRACE(ALL_TRACE, " "); Timer_traceHead(); HTTRACE(ALL_TRACE, "\n"); for (v = 0; v < HT_M_HASH_SIZE; v++) { cur = HashTable[v]; while ((pres = (SockEvents *) HTList_nextObject(cur)) != NULL) { int i; HTTRACE(ALL_TRACE, "%3d \n" _ pres->s); for (i = 0; i < HTEvent_TYPES; i++) if (pres->events[i]) { static char * names[HTEvent_TYPES] = {"read", "writ", "xcpt"}; HTTRACE(ALL_TRACE, "%s " _ names[i]); Event_trace(pres->events[i]); HTTRACE(ALL_TRACE, " "); Timer_trace(pres->timeouts[i]); HTTRACE(ALL_TRACE, " "); } HTTRACE(ALL_TRACE, "\n"); } }}PRIVATE void fd_dump (SOCKET maxfs, fd_set * rset, fd_set * wset, fd_set * oset, struct timeval * wt){ SOCKET cnt; /* Check read set */ HTTRACE(THD_TRACE, "............ READ :"); for (cnt=0; cnt<=maxfs; cnt++) if (FD_ISSET(cnt, rset)) HTTRACE(THD_TRACE, " %d" _ cnt); HTTRACE(THD_TRACE, "\n"); /* Check write set */ HTTRACE(THD_TRACE, "............ WRITE:"); for (cnt=0; cnt<=maxfs; cnt++) if (FD_ISSET(cnt, wset)) HTTRACE(THD_TRACE, " %d" _ cnt); HTTRACE(THD_TRACE, "\n"); /* Check oob set */ HTTRACE(THD_TRACE, "............ OOB :"); for (cnt=0; cnt<=maxfs; cnt++) if (FD_ISSET(cnt, oset)) HTTRACE(THD_TRACE, " %d" _ cnt); HTTRACE(THD_TRACE, "\n"); if (wt) HTTRACE(THD_TRACE, "............ Timeout is %ld s, %ld microsecs\n" _ wt->tv_sec _ wt->tv_usec);}#endif /* HTDEBUG *//* ------------------------------------------------------------------------- *//* EVENT TIMING FUNCTIONS *//* ------------------------------------------------------------------------- */#ifdef WWW_WIN_ASYNCPRIVATE BOOL Timer_setWindowsTimer (HTTimer * timer){ unsigned long id; HWND hwnd = SBinetHTEventList_getWinHandle(&id); BOOL status = (SetTimer(hwnd, (UINT_PTR)timer, (UINT)HTTimer_getTime(timer), NULL) == 0) ? NO : YES; return status;}PRIVATE BOOL Timer_deleteWindowsTimer (HTTimer * timer){ unsigned long id; HWND hwnd = SBinetHTEventList_getWinHandle(&id); BOOL status = (KillTimer(hwnd, (UINT_PTR)timer) == 0) ? NO : YES; return status;}#endif /* WWW_WIN_ASYNC *//*** Event timeout handler** If an event didn't occur before the timeout then call it explicitly** indicating that it timed out.*/PRIVATE int EventListTimerHandler (HTTimer * timer, void * param, HTEventType type){ SockEvents * sockp = (SockEvents *) param; HTEvent * event = NULL; /* Check for read timeout */ if (sockp->timeouts[HTEvent_INDEX(HTEvent_READ)] == timer) { event = sockp->events[HTEvent_INDEX(HTEvent_READ)]; HTTRACE(THD_TRACE, "Event....... READ timed out on %d.\n" _ sockp->s); return (*event->cbf) (sockp->s, event->param, HTEvent_TIMEOUT); } /* Check for write timeout */ if (sockp->timeouts[HTEvent_INDEX(HTEvent_WRITE)] == timer) { event = sockp->events[HTEvent_INDEX(HTEvent_WRITE)]; HTTRACE(THD_TRACE, "Event....... WRITE timed out on %d.\n" _ sockp->s); return (*event->cbf) (sockp->s, event->param, HTEvent_TIMEOUT); } /* Check for out-of-band data timeout */ if (sockp->timeouts[HTEvent_INDEX(HTEvent_OOB)] == timer) { event = sockp->events[HTEvent_INDEX(HTEvent_OOB)]; HTTRACE(THD_TRACE, "Event....... OOB timed out on %d.\n" _ sockp->s); return (*event->cbf) (sockp->s, event->param, HTEvent_TIMEOUT); } HTTRACE(THD_TRACE, "Event....... No event for timer %p with context %p\n" _ timer _ param); return HT_ERROR;}PRIVATE void CheckSockEvent (HTTimer * timer, HTTimerCallback * cbf, void * param){ SockEvents * sockp = (SockEvents *)param; if (cbf == EventListTimerHandler && sockp->timeouts[0] != timer && sockp->timeouts[1] != timer && sockp->timeouts[2] != timer) { HTDEBUGBREAK("Bad timer %p\n" _ timer); }}/* ------------------------------------------------------------------------- *//* EVENT ORDERING STUFF *//* ------------------------------------------------------------------------- */PRIVATE SockEvents * SockEvents_get (SOCKET s, SockEvents_action action){ long v = HASH(s); HTList* cur; SockEvents * pres; /* if the socket doesn't exists, don't do anything */ if (s == INVSOC) return NULL; if (HashTable[v] == NULL) HashTable[v] = HTList_new(); cur = HashTable[v]; while ((pres = (SockEvents *) HTList_nextObject(cur)) != NULL) if (pres->s == s) return pres; if (action == SockEvents_mayCreate) { if ((pres = (SockEvents *) HT_CALLOC(1, sizeof(SockEvents))) == NULL) HT_OUTOFMEM("SBinetHTEventList_register"); pres->s = s; HTList_addObject(HashTable[v], (void *)pres); return pres; } return NULL;}PRIVATE int EventOrder_add (SOCKET s, HTEventType type, ms_t now){ EventOrder * pres; HTList * cur = EventOrderList; HTList * insertAfter = cur; SockEvents * sockp = SockEvents_get(s, SockEvents_find); HTEvent * event; if (sockp == NULL || (event = sockp->events[HTEvent_INDEX(type)]) == NULL) { HTTRACE(THD_TRACE, "EventOrder.. no event found for socket %d, type %s.\n" _ s _ HTEvent_type2str(type)); // Don't abort the whole IO thread for one transient condition. // Hopefully, this socket will be unregistered soon anyway. return HT_OK; } /* Fixup the timeout */ if (sockp->timeouts[HTEvent_INDEX(type)]) HTTimer_refresh(sockp->timeouts[HTEvent_INDEX(type)], now); /* Look to see if it's already here from before */ while ((pres = (EventOrder *) HTList_nextObject(cur))) { if (pres->s == s && pres->event == event && pres->type == type) { // tmp is required to eliminate Microsoft compiler error since // this increments an enum int tmp = ((int) pres->skipped) + 1; pres->skipped = (HTPriority) tmp; return HT_OK; } if (pres->event->priority+pres->skipped > event->priority) insertAfter = cur; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -