Exemple #1
0
/*
**  When a timer has expired, we dispatch the event handler and re-register the
**  timer with the next expiration time if repetitive. Otherwise we just leave
**  it
*/
PRIVATE int Timer_dispatch (HTList * cur, HTList * last)
{
    HTTimer * timer;
    int ret = HT_ERROR;

    timer = (HTTimer *)HTList_objectOf(cur);
    if (timer == NULL) {
#if 0
        HTDEBUGBREAK("Timer dispatch couldn't find a timer\n");
#endif
        CLEARME(timer);
	return HT_ERROR;
    }
#ifdef WWW_WIN_ASYNC
    /* 2000/07/31 Jens Meggers ([email protected]):
       On Windows, timers are always repetitive, so we have to delete the 
       timer */
    if (DeletePlatformTimer)
      DeletePlatformTimer(timer);
#endif /* WWW_WIN_ASYNC */
    if (timer->repetitive)
	HTTimer_new(timer, timer->cbf, timer->param, timer->millis, YES, YES);
    else
	HTList_quickRemoveElement(cur, last);
    HTTRACE(THD_TRACE, "Timer....... Dispatch timer %p\n" _ timer);
    ret = (*timer->cbf) (timer, timer->param, HTEvent_TIMEOUT);
    return ret;
}
Exemple #2
0
/* 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);
}
Exemple #3
0
PUBLIC 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);
    }
}
Exemple #4
0
PRIVATE int ReturnEvent (HTTimer * timer, void * param, HTEventType type)
{
    file_info * file = (file_info *) param;
    if (timer != file->timer)
	HTDEBUGBREAK("File timer %p not in sync\n" _ timer);
    HTTRACE(PROT_TRACE, "HTLoadFile.. Continuing %p with timer %p\n" _ file _ timer);

    /*
    **  Delete the timer
    */
    HTTimer_delete(file->timer);
    file->timer = NULL;

    /*
    **  Now call the event again
    */
    return FileEvent(INVSOC, file, HTEvent_READ);
}
Exemple #5
0
PRIVATE int FlushEvent (HTTimer * timer, void * param, HTEventType type)
{
    HTOutputStream * me = (HTOutputStream *) param;
    if (me->timer && timer != me->timer)
	HTDEBUGBREAK("Buffer Writer timer %p not in sync\n" _ timer);
    HTTRACE(PROT_TRACE, "Buffer...... Timeout flushing %p with timer %p\n" _ me _ timer);

    /*
    **  We ignore the return code here which we shouldn't!!!
    */
    HTBufferWriter_flush(me);

    /*
    **  Delete the timer
    */
    HTTimer_delete(me->timer);
    me->timer = NULL;
    return HT_OK;
}
Exemple #6
0
PRIVATE int SocketEvent (SOCKET soc, void * pVoid, HTEventType type)
{
    raw_info * raw = (raw_info *) pVoid;
    int status = HT_ERROR;
    HTNet * net = raw->net;
    HTRequest * request = raw->request;
    HTHost * host = HTNet_host(net);

    /*
    **  Check whether we have been interrupted or timed out
    */
    if (type == HTEvent_BEGIN) {
	raw->state = RAW_BEGIN;
    } else if (type == HTEvent_CLOSE) {			      /* Interrupted */
	RawCleanup(request, HT_INTERRUPTED);
	return HT_OK;
    } else if (type == HTEvent_TIMEOUT) {
	HTRequest_addError(request, ERR_FATAL, NO, HTERR_TIME_OUT,
			   NULL, 0, "HTLoadSocket");
	RawCleanup(request, HT_TIMEOUT);
	return HT_OK;
    } else if (type == HTEvent_END) {
	RawCleanup(request, HT_OK);
	return HT_OK;
    }
	
    /* Now jump into the state machine */
    while (1) {
	switch(raw->state) {
	case RAW_BEGIN:
	    status = HTHost_accept(host, net, NULL);
	    host = HTNet_host(net);
            if (status == HT_OK) {
		raw->state = RAW_NEED_STREAM;
	    } else if (status == HT_WOULD_BLOCK || status == HT_PENDING) {
		return HT_OK;
	    } else	
		raw->state = RAW_ERROR;	       /* Error or interrupt */
	    break;

	case RAW_NEED_STREAM:
	{
	    /* 
	    ** Create the stream pipe FROM the channel to the application.
	    ** The target for the input stream pipe is set up using the
	    ** stream stack.
	    */
            HTStream * in_stream =
		HTStreamStack(WWW_RAW,
			      HTRequest_outputFormat(request),
			      HTRequest_outputStream(request),
			      request, YES);
	    HTNet_setReadStream(net, in_stream);
            HTRequest_setOutputConnected(request, YES);

	    raw->state = RAW_READ;
	    break;
	}

	case RAW_READ:
	    status = HTHost_read(host, net);
	    if (status == HT_WOULD_BLOCK)
		return HT_OK;
	    else if (status==HT_CLOSED)
		raw->state = RAW_OK;
	    else 
		raw->state = RAW_ERROR;
	    break;

	case RAW_OK:
	    RawCleanup(request, HT_OK);
	    return HT_OK;
	    break;

	case RAW_ERROR:
	    RawCleanup(request, HT_ERROR);
	    return HT_OK;
	    break;

	default:
	    HTDEBUGBREAK("Bad raw state %d\n" _ raw->state);
	}
    }
    return HT_OK;
}
Exemple #7
0
PUBLIC HTTimer * HTTimer_new (HTTimer * timer, HTTimerCallback * cbf,
			      void * param, ms_t millis, BOOL relative,
			      BOOL repetitive)
{
    HTList * last;
    HTList * cur;
    ms_t now = HTGetTimeInMillis();
    ms_t expires;
    HTTimer * pres;

    CHECKME(timer);
    expires = millis;
    if (relative)
	expires += now;
    else
	millis = expires-now;

    if (Timers == NULL)
	Timers = HTList_new();

    if (timer) {

	/*	if a timer is specified, it should already exist
	 */
	if ((cur = HTList_elementOf(Timers, (void *)timer, &last)) == NULL) {
	    HTDEBUGBREAK("Timer %p not found\n" _ timer);
	    CLEARME(timer);
	    return NULL;
	}
	HTList_quickRemoveElement(cur, last);
	HTTRACE(THD_TRACE, "Timer....... Found timer %p with callback %p, context %p, and %s timeout %d\n" _ 
		    timer _ cbf _ param _ relative ? "relative" : "absolute" _ millis);
	/* could optimize by sorting from last when ((HTList *)(last->object))->expires < expires (most common case) */
    } else {

	/*	create a new timer
	 */
	if ((timer = (HTTimer *) HT_CALLOC(1, sizeof(HTTimer))) == NULL)
	    HT_OUTOFMEM("HTTimer_new");
	last = Timers;
	HTTRACE(THD_TRACE, "Timer....... Created %s timer %p with callback %p, context %p, and %s timeout %d\n" _ 
		    repetitive ? "repetitive" : "one shot" _ 
		    timer _ cbf _ param _ 
		    relative ? "relative" : "absolute" _ millis);
    }

    /*
    **  Sort new element into list
    */
    for (cur = last; 
	 (pres = (HTTimer *) HTList_nextObject(cur)) != NULL && pres->expires < expires; 
	 last = cur);

    /*
    **  If the expiration is 0 then we still register it but dispatch it immediately.
    */
    if (!millis) HTTRACE(THD_TRACE, "Timer....... Timeout is 0 - expires NOW\n");

    timer->expires = expires;
    timer->cbf = cbf;
    timer->param = param;
    timer->millis = millis;
    timer->relative = relative;
    timer->repetitive = repetitive;
    SETME(timer);

    /*
    **	add to list if timer is new
    */
    cur = HTList_addList(last, (void *)timer);

    /*
    **  Call any platform specific timer handler
    */
    if (SetPlatformTimer) SetPlatformTimer(timer);

    /* Check if the timer object has already expired. If so then dispatch */
    if (timer->expires <= now) Timer_dispatch(cur, last);

    CLEARME(timer);
    return timer;
}