Exemplo n.º 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;
}
Exemplo n.º 2
0
PUBLIC BOOL HTTimer_delete (HTTimer * timer)
{
    HTList * last;
    HTList * cur;
    CHECKME(timer);
    if ((cur = HTList_elementOf(Timers, (void *)timer, &last)) == NULL) CLEARME(timer);
    if (HTList_quickRemoveElement(cur, last)) {
	HTTRACE(THD_TRACE, "Timer....... Deleted active timer %p\n" _ timer);
    } else { 
	HTTRACE(THD_TRACE, "Timer....... Deleted expired timer %p\n" _ timer);
    }

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

    CLEARME(timer);
    HT_FREE(timer);
    return YES;
}
Exemplo n.º 3
0
PUBLIC BOOL HTAnchor_delete (HTParentAnchor * me)
{
    /* Don't delete if document is loaded */
    if (!me || me->document) {
	HTTRACE(ANCH_TRACE, "Anchor...... Not deleted\n");
	return NO;
    }

    /* Recursively try to delete target anchors */
    delete_links ((HTAnchor *) me);

    if (!HTList_isEmpty(me->sources)) {    /* There are still incoming links */

	/*
	** Delete all outgoing links from children, if any
	*/
	if (me->children) {
	    int cnt = 0;
	    for (; cnt<CHILD_HASH_SIZE; cnt++) {
		HTList * kids = me->children[cnt];
		if (kids) {
		    HTChildAnchor * child;
		    while ((child = (HTChildAnchor *) HTList_nextObject(kids)))
			delete_links((HTAnchor *) child);
		    return NO;	/* Parent not deleted */
		}
	    }
	}

	/*
	** No more incoming links : kill everything
	** First, recursively delete children
	*/
	if (me->children) {
	    int cnt = 0;
	    for (; cnt<CHILD_HASH_SIZE; cnt++) {
		HTList * kids = me->children[cnt];
		if (kids) {
		    HTChildAnchor * child;
		    while ((child=(HTChildAnchor *) HTList_removeLastObject(kids)))
			delete_links((HTAnchor *) child);
		    HT_FREE(child->tag);
		    HT_FREE(child);
		}
	    }
	}
    }

    /* 2001/03/06: Bug fix by Serge Adda <*****@*****.**>
       HTAnchor_delete wasn't removing the reference to the deleted
       anchor. This caused a bug whenever requesting another anchor
       for the same URL.
    */
    if (adult_table) {
      int hash;
      const char *p;
      HTList * adults;
      HTList * grownups;
      HTList * last;
      HTParentAnchor * foundAnchor;

      /* Select list from hash table */
      for(p=me->address, hash=0; *p; p++)
	hash = (int) ((hash * 3 + (*(unsigned char*)p)) %
		      PARENT_HASH_SIZE);
      adults = adult_table[hash];

      /* Search list for anchor */
      grownups = adults;
      last = grownups;
      while ((foundAnchor = (HTParentAnchor *)
	      HTList_nextObject(grownups))){
	if (!strcmp(foundAnchor->address, me->address)) {
	  HTList_quickRemoveElement (grownups, last);
	  break;
	}
	last = grownups;
      }
    }

    /* Now kill myself */
    delete_parent(me);
    return YES;  /* Parent deleted */
#if 0
  if (! HTList_isEmpty (me->sources)) {  /* There are still incoming links */
    /* Delete all outgoing links from children, if any */
    HTList *kids = me->children;
    while ((child = (HTChildAnchor *) HTList_nextObject (kids)))
      delete_links ((HTAnchor *) child);
    return NO;  /* Parent not deleted */
  }

  /* No more incoming links : kill everything */
  /* First, recursively delete children */
  while ((child = (HTChildAnchor *) HTList_removeLastObject (me->children))) {
    delete_links ((HTAnchor *) child);
    HT_FREE(child->tag);
    HT_FREE(child);
  }
#endif
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
0
/*
** 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.
*/
PUBLIC int HTEventList_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))) {
        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, "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;
}