📄 sbhtevtlst.cpp
字号:
/* Create a new element */ if ((pres = (EventOrder *) HT_CALLOC(1, sizeof(EventOrder))) == NULL) HT_OUTOFMEM("EventOrder_add"); pres->event = event; pres->s = s; pres->type = type; HTList_addObject(insertAfter, (void *)pres); return HT_OK;}PRIVATE int EventOrder_executeAndDelete (void) { HTList * cur = EventOrderList; EventOrder * pres; int i = 0; HTTRACE(THD_TRACE, "EventOrder.. execute ordered events\n"); if (cur == NULL) return NO; while (((pres=(EventOrder *) HTList_removeLastObject(cur)) != NULL) && (i<EVENTS_TO_EXECUTE)) { HTEvent * event = pres->event; int ret; HTTRACE(THD_TRACE, "EventList... calling socket %d, request %p handler %p type %s\n" _ pres->s _ (void *) event->request _ (void *) event->cbf _ HTEvent_type2str(pres->type)); ret = (*pres->event->cbf)(pres->s, pres->event->param, pres->type); HT_FREE(pres); if (ret != HT_OK) return ret; i++; } return HT_OK;}PRIVATE BOOL EventOrder_clearAll (void){ HTList * cur = EventOrderList; EventOrder * pres; HTTRACE(THD_TRACE, "EventOrder.. Clearing all ordered events\n"); if (cur) { while ((pres = (EventOrder *) HTList_nextObject(cur)) != NULL) HT_FREE(pres); return YES; } return NO;}PRIVATE BOOL EventOrder_deleteAll (void) { EventOrder_clearAll(); HTList_delete(EventOrderList); EventOrderList = NULL; return YES;}/* ------------------------------------------------------------------------- *//* EVENT REGISTRATION *//* ------------------------------------------------------------------------- *//*** ResetMaxSock - reset the value of the maximum socket in use */#ifndef WWW_WIN_ASYNCPRIVATE void __ResetMaxSock (void){ SOCKET cnt; SOCKET t_max = 0; SOCKET old_max = MaxSock; for (cnt = 0 ; cnt <= MaxSock; cnt++) { if (FD_ISSET(cnt, (FdArray + HTEvent_INDEX(HTEvent_READ))) || FD_ISSET(cnt, (FdArray + HTEvent_INDEX(HTEvent_WRITE))) || FD_ISSET(cnt, (FdArray + HTEvent_INDEX(HTEvent_OOB)))) if (cnt > t_max) t_max = cnt; } MaxSock = t_max+1; HTTRACE(THD_TRACE, "Event....... Reset MaxSock from %u to %u\n" _ old_max _ MaxSock); return;} #endif /* !WWW_WIN_ASYNC */PRIVATE int EventList_remaining (SockEvents * pres){ int ret = 0; int i; for (i = 0; i < HTEvent_TYPES; i++) if (pres->events[i] != NULL) ret |= 1<<i; return ret;}/*** For a given socket, reqister a request structure, a set of operations, ** a HTEventCallback function, and a priority. For this implementation, ** we allow only a single HTEventCallback function for all operations.** and the priority field is ignored.*/int SBinetHTEventList_register (SOCKET s, HTEventType type, HTEvent * event){ int newset = 0; SockEvents * sockp; HTTRACE(THD_TRACE, "Event....... Register socket %d, request %p handler %p type %s at priority %d\n" _ s _ (void *) event->request _ (void *) event->cbf _ HTEvent_type2str(type) _ (unsigned) event->priority); if (s==INVSOC || HTEvent_INDEX(type) >= HTEvent_TYPES) return 0; /* ** Insert socket into appropriate file descriptor set. We also make sure ** that it is registered in the global set. */ HTTRACE(THD_TRACE, "Event....... Registering socket for %s\n" _ HTEvent_type2str(type)); sockp = SockEvents_get(s, SockEvents_mayCreate); sockp->s = s; sockp->events[HTEvent_INDEX(type)] = event; newset = EventList_remaining(sockp);#ifdef WWW_WIN_ASYNC if (WSAAsyncSelect(s, HTSocketWin, HTwinMsg, HTEvent_BITS(newset)) < 0) { HTTRACE(THD_TRACE, "Event....... WSAAsyncSelect returned `%s'!" _ HTErrnoString(socerrno)); return HT_ERROR; }#else /* WWW_WIN_ASYNC */ FD_SET(s, FdArray+HTEvent_INDEX(type)); HTTRACEDATA((char *) FdArray+HTEvent_INDEX(type), 8, "SBinetHTEventList_register: (s:%d)" _ s); if (s > MaxSock) { MaxSock = s ; HTTRACE(THD_TRACE, "Event....... New value for MaxSock is %d\n" _ MaxSock); }#endif /* !WWW_WIN_ASYNC */ /* ** If the timeout has been set (relative in millis) then we register ** a new timeout for this event unless we already have a timer. */ if (event->millis >= 0) { sockp->timeouts[HTEvent_INDEX(type)] = HTTimer_new(sockp->timeouts[HTEvent_INDEX(type)], EventListTimerHandler, sockp, event->millis, YES, YES); } return HT_OK;}/*** Remove the registered information for the specified socket for the actions ** specified in ops. if no actions remain after the unregister, the registered** info is deleted, and, if the socket has been registered for notification, ** the HTEventCallback will be invoked.*/int SBinetHTEventList_unregister (SOCKET s, HTEventType type) { long v = HASH(s); HTList * cur = HashTable[v]; HTList * last = cur; SockEvents * pres; int ret = HT_ERROR; /* if the socket doesn't exists, don't do anything */ if (s == INVSOC) return HT_OK; while (cur && (pres = (SockEvents *) HTList_nextObject(cur)) != NULL) { if (pres->s == s) { int remaining = 0; /* ** Unregister the event from this action */ pres->events[HTEvent_INDEX(type)] = NULL; remaining = EventList_remaining(pres); /* ** Check to see of there was a timeout connected with the event. ** If so then delete the timeout as well. */ { HTTimer * timer = pres->timeouts[HTEvent_INDEX(type)]; if (timer) HTTimer_delete(timer); pres->timeouts[HTEvent_INDEX(type)] = NULL; } #ifdef WWW_WIN_ASYNC if (WSAAsyncSelect(s, HTSocketWin, HTwinMsg, remaining) < 0) ret = HT_ERROR;#else /* WWW_WIN_ASYNC */ FD_CLR(s, FdArray+HTEvent_INDEX(type)); HTTRACEDATA((char*)FdArray+HTEvent_INDEX(type), 8, "SBinetHTEventList_unregister: (s:%d)" _ s);#endif /* !WWW_WIN_ASYNC */ /* ** Check to see if we can delete the action completely. We do this ** if there are no more events registered. */ if (remaining == 0) { HTList * doomed = cur; HTTRACE(THD_TRACE, "Event....... No more events registered for socket %d\n" _ s);#ifndef WWW_WIN_ASYNC /* Check to see if we have to update MaxSock */ if (pres->s >= MaxSock) __ResetMaxSock();#endif /* !WWW_WIN_ASYNC */ HT_FREE(pres); pres = (SockEvents *) HTList_nextObject(cur); HTList_quickRemoveElement(doomed, last); } ret = HT_OK; HTTRACE(THD_TRACE, "Event....... Socket %d unregistered for %s\n" _ s _ HTEvent_type2str(type)); /* We found the socket and can break */ break; } last = cur; } if (THD_TRACE) { if (ret == HT_ERROR) HTTRACE(THD_TRACE, "Event....... Couldn't find socket %d. Can't unregister type %s\n" _ s _ HTEvent_type2str(type)); } return ret;}/*** Unregister all sockets ** N.B. we just remove them for our internal data structures: it is up to the ** application to actually close the socket. */int SBinetHTEventList_unregisterAll (void) { int i; HTTRACE(THD_TRACE, "Unregister.. all sockets\n"); for (i = 0 ; i < HT_M_HASH_SIZE; i++) { HTList * cur = HashTable[i]; SockEvents * pres; while ((pres = (SockEvents *) HTList_nextObject(cur)) != NULL) {#ifdef WWW_WIN_ASYNC WSAAsyncSelect(pres->s, HTSocketWin, HTwinMsg, 0);#endif /* WWW_WIN_ASYNC */ HT_FREE(pres); } HTList_delete(HashTable[i]); HashTable[i] = NULL; }#ifndef WWW_WIN_ASYNC MaxSock = 0 ; HTTRACE(THD_TRACE, "Event....... New value for MaxSock is %d\n" _ MaxSock); FD_ZERO(FdArray+HTEvent_INDEX(HTEvent_READ)); FD_ZERO(FdArray+HTEvent_INDEX(HTEvent_WRITE)); FD_ZERO(FdArray+HTEvent_INDEX(HTEvent_OOB));#endif /* !WWW_WIN_ASYNC */ EventOrder_deleteAll(); return 0;}/*** Dispatch the event to the appropriate event handler.** If no event handler is found then just return.*/int SBinetHTEventList_dispatch (SOCKET s, HTEventType type, ms_t now){ SockEvents * sockp = SockEvents_get(s, SockEvents_find); if (sockp) { HTEvent * event = sockp->events[HTEvent_INDEX(type)]; /* Fixup the timeout */ if (sockp->timeouts[HTEvent_INDEX(type)]) HTTimer_refresh(sockp->timeouts[HTEvent_INDEX(type)], now); /* ** If we have found an event object for this event then see ** is we should call it. */ if (event && event->priority!=HT_PRIORITY_OFF) return (*event->cbf) (s, event->param, type); HTTRACE(THD_TRACE, "Dispatch.... Handler %p NOT called\n" _ sockp); return HT_OK; } HTTRACE(THD_TRACE, "Dispatch.... Bad socket %d\n" _ s); return NO;}SBPUBLIC HTEvent * SBinetHTEventList_lookup (SOCKET s, HTEventType type){ SockEvents * sockp = NULL; if ((sockp = SockEvents_get(s, SockEvents_find)) == NULL) return NULL; return sockp->events[HTEvent_INDEX(type)];}/* ------------------------------------------------------------------------- *//* THE EVENT LOOP *//* ------------------------------------------------------------------------- *//* * Modifed version of event loop for SBinet, includes locking *//*** Stops the event loop. The function does not guarantee** that all requests have terminated. This is for the app to do*/SBPUBLIC void SBinetHTEventList_stopLoop (void){ HTEndLoop = 1;}/*** There are now two versions of the event loop. The first is if you want** to use async I/O on windows, and the other is if you want to use normal** Unix setup with sockets*/SBPUBLIC int SBinetHTEventList_newLoop (void){ /* printf("Thread %x entering event loop\n",VXItrdThreadGetID()); */#ifdef WWW_WIN_ASYNC MSG msg; int status; /* * New SBinet Event loop with locking */ while (!HTEndLoop && GetMessage(&msg,0,0,0)) { //if(msg.lParam > 1024) break; // See SPR 7850 for reason SBinetInterface::LockLibwww( ); TranslateMessage(&msg); DispatchMessage(&msg); // Loop over rest of messages in queue before giving up Inet while (!HTEndLoop && PeekMessage(&msg,0,0,0,PM_REMOVE)) { //if(msg.lParam > 1024) break; // See SPR 7850 for reason TranslateMessage(&msg); DispatchMessage(&msg); } SBinetInterface::UnlockLibwww( ); } status = HTEndLoop; /* Reset HTEndLoop in case we want to start again */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -