⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 htevtlst.c

📁 www工具包. 这是W3C官方支持的www支撑库. 其中提供通用目的的客户端的WebAPI: complete HTTP/1.1 (with caching, pipelining, PUT, POS
💻 C
📖 第 1 页 / 共 2 页
字号:
	    }	    #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, "HTEventList_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. */PUBLIC int HTEventList_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))) {#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.*/PUBLIC int HTEventList_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;}PUBLIC HTEvent * HTEventList_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 		 		     *//* ------------------------------------------------------------------------- *//***  Start eventloop*/PUBLIC int HTEventList_newLoop (void){    return HTEventList_loop (NULL);}/***  Stops the event loop. The function does not guarantee**  that all requests have terminated. This is for the app to do*/PUBLIC void HTEventList_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*/PUBLIC int HTEventList_loop (HTRequest * theRequest){#ifdef WWW_WIN_ASYNC    MSG msg;    int status;    while (!HTEndLoop && GetMessage(&msg,0,0,0)) {	    TranslateMessage(&msg);	    DispatchMessage(&msg);    }    status = HTEndLoop;        /* Reset HTEndLoop in case we want to start again */    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;	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 interruted - 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;	/* 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)		    goto stop_loop;	    if (FD_ISSET(s, &twriteset))		if ((status = EventOrder_add(s, HTEvent_WRITE, now)) != HT_OK)		    goto stop_loop;	    if (FD_ISSET(s, &treadset))		if ((status = EventOrder_add(s, HTEvent_READ, now)) != HT_OK)		    goto stop_loop;	}	if ((status = EventOrder_executeAndDelete()) != 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 AsyncWindowProc(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 (HTEventList_dispatch((int)sock, type, now) != HT_OK)	HTEndLoop = -1;    return (0);}/*	HTEventList_get/setWinHandle**	--------------------------**	Managing the windows handle on Windows*/PUBLIC BOOL HTEventList_setWinHandle (HWND window, unsigned long message){    HTSocketWin = window;    HTwinMsg = message;    return YES;}PUBLIC HWND HTEventList_getWinHandle (unsigned long * pMessage){    if (pMessage)        *pMessage = HTwinMsg;    return (HTSocketWin);}#endif /* WWW_WIN_ASYNC */PUBLIC BOOL HTEventInit (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)AsyncWindowProc;    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))) {#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, "HTEventInit. Can't initialize WinSoc\n");            WSACleanup();            return NO;        }        if (wsadata.wVersion < MINIMUM_WINSOCK_VERSION) {            HTTRACE(THD_TRACE, "HTEventInit. Bad version of WinSoc\n");            WSACleanup();            return NO;        }	HTTRACE(APP_TRACE, "HTEventInit. Using WinSoc version \"%s\".\n" _ 		    wsadata.szDescription);    }#endif /* _WINSOCKAPI_ */    HTEvent_setRegisterCallback(HTEventList_register);    HTEvent_setUnregisterCallback(HTEventList_unregister);    return YES;}PUBLIC BOOL HTEventTerminate (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 + -