📄 sbhtevtlst.cpp
字号:
HTEndLoop = 0; return (status == 1 ? HT_OK : HT_ERROR);#else /* WWW_WIN_ASYNC */ fd_set treadset, twriteset, texceptset; struct timeval waittime, * wt; int active_sockets; int maxfds; ms_t timeout; ms_t now; SOCKET s; int status = HT_OK; /* Check that we don't have multiple loops started at once */ if (HTInLoop) { HTTRACE(THD_TRACE, "Event Loop.. Already one loop running - exiting\n"); return HT_ERROR; } HTInLoop = YES; /* Set up list of events - is kept around until EventOrder_deleteAll */ if (!EventOrderList) EventOrderList = HTList_new(); else EventOrder_clearAll(); /* Don't leave this loop until we leave the application */ while (!HTEndLoop) { /* ** Timeval struct copy needed for linux, as it set the value to the ** remaining timeout while exiting the select. (and perhaps for ** other OS). Code borrowed from X server. */ wt = NULL; if ((status = HTTimer_next(&timeout))) break; /* * This is a hack, we really should check the fd_sets for emptiness and use a trdTimer * Requesting threads could wake the timer -dg 6/7/01 */ if(timeout == 0) timeout = 100; if (timeout != 0) { waittime.tv_sec = timeout / MILLI_PER_SECOND; waittime.tv_usec = (timeout % MILLI_PER_SECOND) * (1000000 / MILLI_PER_SECOND); wt = &waittime; } /* ** Check whether we still have to continue the event loop. It could ** be that one of the timer handlers ended the loop. */ if (HTEndLoop) break; /* ** Now we copy the current active file descriptors to pass them to select. */ treadset = FdArray[HTEvent_INDEX(HTEvent_READ)]; twriteset = FdArray[HTEvent_INDEX(HTEvent_WRITE)]; texceptset = FdArray[HTEvent_INDEX(HTEvent_OOB)]; /* And also get the max socket value */ maxfds = MaxSock; HTTRACE(THD_TRACE, "Event Loop.. calling select: maxfds is %d\n" _ maxfds);#ifdef HTDEBUG fd_dump(maxfds, &treadset, &twriteset, &texceptset, wt);#endif#ifdef __hpux active_sockets = select(maxfds+1, (int *)&treadset, (int *)&twriteset, (int *)&texceptset, wt);#elif defined(_WINSOCKAPI_) /* * yovavm@contact.com * * On some WINSOCK versions select() with 3 empty sets and NULL timeout * returns 0 and in some it returns -1. * If 0 is returned in such situation, we will go into an infinite loop * (cause the sets will stay empty forever ...), * so make sure to set the active_sockets = -1 which will take us out * of the loop. */ if ((treadset.fd_count || twriteset.fd_count || texceptset.fd_count) && wt) active_sockets = select(maxfds+1, &treadset, &twriteset, &texceptset, wt); else active_sockets = -1; #else active_sockets = select(maxfds+1, &treadset, &twriteset, &texceptset, wt);#endif now = HTGetTimeInMillis(); HTTRACE(THD_TRACE, "Event Loop.. select returns %d\n" _ active_sockets);#ifdef HTDEBUG fd_dump(maxfds, &treadset, &twriteset, &texceptset, wt);#endif if (active_sockets == -1) {#ifdef EINTR if (socerrno == EINTR) { /* ** EINTR The select() function was interrupted before any ** of the selected events occurred and before the ** timeout interval expired. ** ** If SA_RESTART has been set for the interrupting ** signal, it is implementation-dependent whether ** select() restarts or returns with EINTR. */ HTTRACE(THD_TRACE, "Event Loop.. select was interrupted - try again\n"); continue; }#endif /* EINTR */#ifdef EBADF if (socerrno == EBADF) { /* ** EBADF One or more of the file descriptor sets specified ** a file descriptor that is not a valid open file ** descriptor. */ HTTRACE(THD_TRACE, "Event Loop.. One or more sockets were not through their connect phase - try again\n"); continue; }#endif HTTRACE(THD_TRACE, "Event Loop.. select returned error %d\n" _ socerrno);#ifdef HTDEBUG EventList_dump();#endif /* HTDEBUG */ status = HT_ERROR; break; } /* ** We had a timeout so now we check and see if we have a timeout ** handler to call. Let HTTimer_next get it. */ if (active_sockets == 0) continue; SBinetInterface::LockLibwww( ); /* There were active sockets. Determine which fd sets they were in */ for (s = 0 ; s <= maxfds ; s++) { if (FD_ISSET(s, &texceptset)) if ((status = EventOrder_add(s, HTEvent_OOB, now)) != HT_OK) { SBinetInterface::UnlockLibwww( ); goto stop_loop; } if (FD_ISSET(s, &twriteset)) if ((status = EventOrder_add(s, HTEvent_WRITE, now)) != HT_OK) { SBinetInterface::UnlockLibwww( ); goto stop_loop; } if (FD_ISSET(s, &treadset)) if ((status = EventOrder_add(s, HTEvent_READ, now)) != HT_OK) { SBinetInterface::UnlockLibwww( ); goto stop_loop; } } status = EventOrder_executeAndDelete(); SBinetInterface::UnlockLibwww( ); if (status != HT_OK) break; } /* Reset HTEndLoop in case we want to start again */ stop_loop: HTEndLoop = 0; HTInLoop = NO; return status;#endif /* !WWW_WIN_ASYNC */}/* ------------------------------------------------------------------------- *//* EVENT INITIALIZATION AND TERMINATION *//* ------------------------------------------------------------------------- */#ifdef WWW_WIN_ASYNC/* Only responsible for WM_TIMER and WSA_AsyncSelect */ PRIVATE LRESULT CALLBACK SBinetAsyncWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ WORD event; SOCKET sock; HTEventType type; ms_t now = HTGetTimeInMillis(); /* timeout stuff */ if (uMsg == WM_TIMER) { HTTimer_dispatch((HTTimer *)wParam); return (0); } if (uMsg != HTwinMsg) /* not our async message */ return (DefWindowProc(hwnd, uMsg, wParam, lParam)); event = LOWORD(lParam); sock = (SOCKET)wParam; switch (event) { case FD_READ: type = HTEvent_READ; break; case FD_WRITE: type = HTEvent_WRITE; break; case FD_ACCEPT: type = HTEvent_ACCEPT; break; case FD_CONNECT: type = HTEvent_CONNECT; break; case FD_OOB: type = HTEvent_OOB; break; /* JK: was returning HTEvent_CLOSE before, and this was a source of errors, as libwww detects the socket shutdown with a call to recv */ case FD_CLOSE: type = HTEvent_READ; break; default: HTDEBUGBREAK("Unknown event %d\n" _ event); } if (SBinetHTEventList_dispatch((int)sock, type, now) != HT_OK) HTEndLoop = -1; return (0);}/* HTEventList_get/setWinHandle** --------------------------** Managing the windows handle on Windows*/SBPUBLIC BOOL SBinetHTEventList_setWinHandle (HWND window, unsigned long message){ HTSocketWin = window; HTwinMsg = message; return YES;}SBPUBLIC HWND SBinetHTEventList_getWinHandle (unsigned long * pMessage){ if (pMessage) *pMessage = HTwinMsg; return (HTSocketWin);}#endif /* WWW_WIN_ASYNC */SBPUBLIC BOOL SBinetHTEventInit (void){#ifdef WWW_WIN_ASYNC /* ** We are here starting a hidden window to take care of events from ** the async select() call in the async version of the event loop in ** the Internal event manager (HTEvtLst.c) */ static char className[] = "AsyncWindowClass"; WNDCLASS wc; OSVERSIONINFO osInfo; wc.style=0; wc.lpfnWndProc=(WNDPROC)SBinetAsyncWindowProc; wc.cbClsExtra=0; wc.cbWndExtra=0; wc.hIcon=0; wc.hCursor=0; wc.hbrBackground=0; wc.lpszMenuName=(LPSTR)0; wc.lpszClassName=className; osInfo.dwOSVersionInfoSize = sizeof(osInfo); GetVersionEx(&osInfo); /* According to Gary Johnson, GetModuleHandle() works for NT as well */#if 0 if (osInfo.dwPlatformId == VER_PLATFORM_WIN32s || osInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) wc.hInstance=GetModuleHandle(NULL); /* 95 and non threaded platforms */ else wc.hInstance=GetCurrentProcess(); /* NT and hopefully everything following */#else wc.hInstance=GetModuleHandle(NULL); /* Should work on all win32 stuff */#endif HTinstance = wc.hInstance; HTclass = RegisterClass(&wc); if (!HTclass) { HTTRACE(THD_TRACE, "HTLibInit.. Can't RegisterClass \"%s\"\n" _ className); return NO; } if ((HTSocketWin = CreateWindow(className, "WWW_WIN_ASYNC", WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, wc.hInstance,0)) == NULL) {#ifdef HTDEBUG char space[50]; HTTRACE(THD_TRACE, "HTLibInit.. Can't Create Window \"WWW_WIN_ASYNC\" - error:"); sprintf(space, "%ld\n", GetLastError()); HTTRACE(THD_TRACE, space);#endif /* HTDEBUG */ return NO; } HTwinMsg = WM_USER; /* use first available message since app uses none */ /* Register platform specific timer handlers for windows */ HTTimer_registerSetTimerCallback(Timer_setWindowsTimer); HTTimer_registerDeleteTimerCallback(Timer_deleteWindowsTimer);#endif /* WWW_WIN_ASYNC */#ifdef _WINSOCKAPI_ /* ** Initialise WinSock DLL. This must also be shut down! PMH */ { WSADATA wsadata; if (WSAStartup(DESIRED_WINSOCK_VERSION, &wsadata)) { HTTRACE(THD_TRACE, "SBinetHTEventInit. Can't initialize WinSock\n"); WSACleanup(); return NO; } if (wsadata.wVersion < MINIMUM_WINSOCK_VERSION) { HTTRACE(THD_TRACE, "SBinetHTEventInit. Bad version of WinSock\n"); WSACleanup(); return NO; } HTTRACE(APP_TRACE, "SBinetHTEventInit. Using WinSoc version \"%s\".\n" _ wsadata.szDescription); }#endif /* _WINSOCKAPI_ */ HTEvent_setRegisterCallback(SBinetHTEventList_register); HTEvent_setUnregisterCallback(SBinetHTEventList_unregister); return YES;}SBPUBLIC BOOL SBinetHTEventTerminate (void){#ifdef _WINSOCKAPI_ WSACleanup();#endif /* _WINSOCKAPI_ */#ifdef WWW_WIN_ASYNC DestroyWindow(HTSocketWin); UnregisterClass((LPCTSTR)HTclass, HTinstance);#endif /* WWW_WIN_ASYNC */ return YES;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -