Пример #1
0
/* match will find a child in the parent, and either replace (if it's an insert) or remove (if data is NULL) */
int xdb_act(xdbcache xc, jid owner, char *ns, char *act, char *match,
	    xmlnode data)
{
	xdbrequest_p cur;
	struct timeval tv;

	if (xc->shutdown)
		return 1;

	if (xc == NULL || owner == NULL || ns == NULL) {
		log_alert("xdb_set",
			  "Programming Error: xdb_set() called with NULL\n");
		return 1;
	}

	log_debug("XDB SET");


	cur = malloc(sizeof(xdbrequest_t));
	memset(cur, 0, sizeof(xdbrequest_t));

	cur->set = 1;
	cur->data = data;
	cur->ns = ns;
	cur->owner = owner;
	cur->act = act;
	cur->match = match;
	gettimeofday(&tv, NULL);
	cur->sent = tv.tv_sec;

	SEM_LOCK(xc->sem);
	cur->id = xc->id++;

	cur->next = xc->first;
	xc->first = cur;

	SEM_UNLOCK(xc->sem);

	/* send it on it's way */
	xdb_deliver(xc->i, cur, 0);
	cur->external = 1;

	/* if it hasn't already returned, we should block here until it returns */
	while (cur->preblock != 1)
		usleep(10);

	/* if it didn't actually get set, flag that */
	if (cur->data == NULL) {
		free(cur);
		return 1;
	}

	xmlnode_free(cur->data);

	free(cur);
	return 0;
}
Пример #2
0
/* match will find a child in the parent, and either replace (if it's an insert) or remove (if data is NULL) */
int xdb_act(xdbcache xc, jid owner, char *ns, char *act, char *match, xmlnode data)
{
    xdbcache newx;
	pool p;

    if(xc == NULL || owner == NULL || ns == NULL)
    {
        fprintf(stderr,"Programming Error: xdb_set() called with NULL\n");
        return 1;
    }

    
    log_debug(ZONE,"XDB SET");

    /* init this newx */
	p = pool_new();
	newx = pmalloco(p, sizeof(_xdbcache));
    newx->i = xc->i;
    newx->set = 1;
    newx->data = data;
    newx->ns = ns;
    newx->act = act;
    newx->match = match;
    newx->owner = owner;
    newx->sent = time(NULL);
    newx->preblock = 0; /* flag */


    pthread_mutex_lock(&(xc->sem));
    newx->id = xc->id++; 
    newx->next = xc->next;
    newx->prev = xc;
    newx->next->prev = newx;
    xc->next = newx; 
    pthread_mutex_unlock(&(xc->sem));

    /* send it on it's way */
    xdb_deliver(xc->i, newx,0);

    /* if it hasn't already returned, we should block here until it returns */
    while (newx->preblock != 1) usleep(10);


    /* if it didn't actually get set, flag that */
    if(newx->data == NULL) {
	  pool_free(p);
	  return 1;
	}

    xmlnode_free(newx->data);

	pool_free(p);

    return 0;
}
Пример #3
0
/* blocks until namespace is retrieved, host must map back to this service! */
xmlnode xdb_get(xdbcache xc, jid owner, char *ns)
{
    xdbcache newx;
    xmlnode x;
	pool p;

    if(xc == NULL || owner == NULL || ns == NULL)
    {
        fprintf(stderr,"Programming Error: xdb_get() called with NULL\n");
        return NULL;
    }

    log_debug(ZONE,"XDB GET");

    /* init this newx */
	p = pool_new();
	newx = pmalloco(p, sizeof(_xdbcache));
    newx->i = xc->i;
    newx->set = 0;
    newx->data = NULL;
    newx->ns = ns;
    newx->owner = owner;
    newx->sent = time(NULL);
    newx->preblock = 0; /* flag */


    pthread_mutex_lock(&(xc->sem));
    newx->id = xc->id++;
    newx->next = xc->next;
    newx->prev = xc;
    newx->next->prev = newx;
    xc->next = newx;
    pthread_mutex_unlock(&(xc->sem));

    /* send it on it's way */
    xdb_deliver(xc->i, newx,0);

    /* if it hasn't already returned, we should block here until it returns */
    while (newx->preblock != 1) usleep(10);

    /* newx.data is now the returned xml packet */

    /* return the xmlnode inside <xdb>...</xdb> */
    for(x = xmlnode_get_firstchild(newx->data); x != NULL && xmlnode_get_type(x) != NTYPE_TAG; x = xmlnode_get_nextsibling(x));

    /* there were no children (results) to the xdb request, free the packet */
    if(x == NULL)
        xmlnode_free(newx->data);

	pool_free(p);

    return x;
}
Пример #4
0
/** resend packets. heartbeat thread */
result xdb_thump(void *arg)
{
    xdbcache xc = (xdbcache)arg;
    xdbcache cur, next;
    int now = time(NULL);

    pthread_mutex_lock(&(xc->sem));
    /* spin through the cache looking for stale requests */
    cur = xc->next;
    while(cur != xc)
    {
        next = cur->next;

        /* really old ones get wacked */
        if((now - cur->sent) > 30)
        {
            /* remove from ring */
            cur->prev->next = cur->next;
            cur->next->prev = cur->prev;

            /* make sure it's null as a flag for xdb_set's */
            cur->data = NULL;

            /* free the thread! */
			cur->preblock = 1;

            cur = next;
            continue;
        }

        /* resend the waiting ones every so often */
        if((now - cur->sent) > 10) {
		  log_alert(ZONE,"Resend xdb packet");
	 	  xdb_deliver(xc->i, cur,1);
		}

        /* cur could have been free'd already on it's thread */
        cur = next;
    }


    pthread_mutex_unlock(&(xc->sem));
    return r_DONE;
}
Пример #5
0
/** resend packets. heartbeat thread */
result xdb_thump(void *arg)
{
	xdbcache xc = (xdbcache) arg;
	xdbrequest_p cur, next, last;
	struct timeval tv;
	time_t now;

	if (xc->shutdown)
		return r_UNREG;

	gettimeofday(&tv, NULL);
	now = tv.tv_sec;

	SEM_LOCK(xc->sem);
	/* spin through the cache looking for stale requests */

	for (last = NULL, cur = xc->first; cur;) {
		next = cur->next;
		if ((cur->external) && ((now - cur->sent) > 30)) {

			if (!last)
				xc->first = next;
			else
				last->next = next;

			cur->data = NULL;
			cur->preblock = 1;
		} else {
			last = cur;

			if ((cur->external) && ((now - cur->sent) > 10)) {
				log_alert("xdb", "Resend xdb packet");
				xdb_deliver(xc->i, cur, 1);
			}
		}

		cur = next;
	}
	SEM_UNLOCK(xc->sem);

	return r_DONE;
}
Пример #6
0
/* blocks until namespace is retrieved, host must map back to this service! */
xmlnode xdb_get(xdbcache xc, jid owner, char *ns)
{
	xdbrequest_p cur;
	xmlnode x;
	struct timeval tv;

	if (xc->shutdown)
		return NULL;

	if (xc == NULL || owner == NULL || ns == NULL) {
		if (ns) {
			log_alert("xdb_get",
				  "Programming Error: xdb_get() called with NULL ns: %s\n",
				  ns);
		} else {
			log_alert("xdb_get",
				  "Programming Error: xdb_get() called with NULL ns: NULL\n");
		}

		if (owner) {
			log_alert("owner", "%s", jid_full(owner));
		}
		return NULL;
	}

	log_debug("XDB GET");

	/* init this newx */
	cur = malloc(sizeof(xdbrequest_t));
	memset(cur, 0, sizeof(xdbrequest_t));
	// cur->set = 0;
	// cur->data = NULL;
	cur->ns = ns;
	cur->owner = owner;
	gettimeofday(&tv, NULL);
	cur->sent = tv.tv_sec;

	SEM_LOCK(xc->sem);
	cur->id = xc->id++;

	cur->next = xc->first;
	xc->first = cur;

	SEM_UNLOCK(xc->sem);

	/* send it on it's way */
	xdb_deliver(xc->i, cur, 0);
	cur->external = 1;

	/* if it hasn't already returned, we should block here until it returns */
	while (cur->preblock != 1)
		usleep(10);

	/* newx.data is now the returned xml packet */

	/* return the xmlnode inside <xdb>...</xdb> */
	for (x = xmlnode_get_firstchild(cur->data);
	     x != NULL && xmlnode_get_type(x) != NTYPE_TAG;
	     x = xmlnode_get_nextsibling(x));

	/* there were no children (results) to the xdb request, free the packet */
	if (x == NULL)
		xmlnode_free(cur->data);

	free(cur);
	return x;
}