Beispiel #1
0
/**
 * em_cache_add:
 * @emc: 
 * @n: 
 * 
 * Add a cache node to the cache, once added the memory is owned by
 * the cache.  If there are conflicts and the old node is still in
 * use, then the new node is not added, otherwise it is added and any
 * nodes older than the expire time are flushed.
 **/
void
em_cache_add(EMCache *emc, EMCacheNode *n)
{
	EMCacheNode *old, *prev;
	EDList old_nodes;

	e_dlist_init(&old_nodes);

	g_mutex_lock(emc->lock);
	old = g_hash_table_lookup(emc->key_table, n->key);
	if (old != NULL) {
		if (old->ref_count == 0) {
			g_hash_table_remove(emc->key_table, old->key);
			e_dlist_remove((EDListNode *)old);
			e_dlist_addtail(&old_nodes, (EDListNode *)old);
			goto insert;
		} else {
			e_dlist_addtail(&old_nodes, (EDListNode *)n);
		}
	} else {
		time_t now;
	insert:
		now = time(0);
		g_hash_table_insert(emc->key_table, n->key, n);
		e_dlist_addhead(&emc->lru_list, (EDListNode *)n);
		n->stamp = now;
		emc->node_count++;

		c(printf("inserting node %s\n", n->key));

		old = (EMCacheNode *)emc->lru_list.tailpred;
		prev = old->prev;
		while (prev && old->stamp < now - emc->timeout) {
			if (old->ref_count == 0) {
				c(printf("expiring node %s\n", old->key));
				g_hash_table_remove(emc->key_table, old->key);
				e_dlist_remove((EDListNode *)old);
				e_dlist_addtail(&old_nodes, (EDListNode *)old);
			}
			old = prev;
			prev = prev->prev;
		}
	}

	g_mutex_unlock(emc->lock);

	while ((old = (EMCacheNode *)e_dlist_remhead(&old_nodes))) {
		emc->node_free(old);
		g_free(old->key);
		g_free(old);
	}
}
/**
 * camel_operation_unref:
 * @cc: operation context
 *
 * Unref and potentially free @cc.
 **/
void
camel_operation_unref (CamelOperation *cc)
{
	GSList *n;

	g_assert(cc->refcount > 0);

	LOCK();
	if (cc->refcount == 1) {
		CamelOperationMsg *msg;

		e_dlist_remove((EDListNode *)cc);

		while ((msg = (CamelOperationMsg *)e_msgport_get(cc->cancel_port)))
			g_free(msg);

		e_msgport_destroy(cc->cancel_port);

		n = cc->status_stack;
		while (n) {
			g_warning("Camel operation status stack non empty: %s", (char *)n->data);
			g_free(n->data);
			n = n->next;
		}
		g_slist_free(cc->status_stack);

		g_free(cc);
	} else {
		cc->refcount--;
	}
	UNLOCK();
}
/**
 * camel_offline_journal_replay:
 * @journal: a #CamelOfflineJournal object
 * @ex: a #CamelException
 *
 * Replay all entries in the journal.
 *
 * Returns %0 on success (no entry failed to replay) or %-1 on fail
 **/
int
camel_offline_journal_replay (CamelOfflineJournal *journal, CamelException *ex)
{
	EDListNode *entry, *next;
	CamelException lex;
	int failed = 0;

	camel_exception_init (&lex);

	entry = journal->queue.head;
	while (entry->next) {
		next = entry->next;
		if (CAMEL_OFFLINE_JOURNAL_GET_CLASS (journal)->entry_play (journal, entry, &lex) == -1) {
			if (failed == 0)
				camel_exception_xfer (ex, &lex);
			camel_exception_clear (&lex);
			failed++;
		} else {
			e_dlist_remove (entry);
		}
		entry = next;
	}

	if (failed > 0)
		return -1;

	return 0;
}
Beispiel #4
0
/**
 * e_event_remove_items:
 * @emp:
 * @handle:
 *
 * Remove items previously added.  They MUST have been previously
 * added, and may only be removed once.
 **/
void
e_event_remove_items(EEvent *emp, void *handle)
{
	struct _event_node *node = handle;

	e_dlist_remove((EDListNode *)node);
	if (node->freefunc)
		node->freefunc(emp, node->events, node->data);
	g_free(node);

	if (emp->priv->sorted) {
		g_slist_foreach(emp->priv->sorted, (GFunc)g_free, NULL);
		g_slist_free(emp->priv->sorted);
		emp->priv->sorted = NULL;
	}
}
Beispiel #5
0
void e_import_class_remove_importer(EImportClass *klass, EImportImporter *f)
{
	struct _EImportImporters *ei, *en;

	ei = (struct _EImportImporters *)klass->importers.head;
	en = ei->next;
	while (en) {
		if (ei->importer == f) {
			e_dlist_remove((EDListNode *)ei);
			if (ei->free)
				ei->free(f, ei->data);
			g_free(ei);
		}
		ei = en;
		en = en->next;
	}
}
Beispiel #6
0
/**
 * em_cache_lookup:
 * @emc: 
 * @key: 
 * 
 * Lookup a cache node.  once you're finished with it, you need to
 * unref it.
 * 
 * Return value: 
 **/
EMCacheNode *
em_cache_lookup(EMCache *emc, const char *key)
{
	EMCacheNode *n;

	g_mutex_lock(emc->lock);
	n = g_hash_table_lookup(emc->key_table, key);
	if (n) {
		e_dlist_remove((EDListNode *)n);
		e_dlist_addhead(&emc->lru_list, (EDListNode *)n);
		n->stamp = time(0);
		n->ref_count++;
	}
	g_mutex_unlock(emc->lock);

	c(printf("looking up '%s' %s\n", key, n?"found":"not found"));

	return n;
}
Beispiel #7
0
void
e_iconv_close(iconv_t ip)
{
	struct _iconv_cache_node *in;

	if (ip == (iconv_t)-1)
		return;

	LOCK();
	in = g_hash_table_lookup(iconv_cache_open, ip);
	if (in) {
		cd(printf("closing iconv converter '%s'\n", in->parent->conv));
		e_dlist_remove((EDListNode *)in);
		in->busy = FALSE;
		e_dlist_addtail(&in->parent->open, (EDListNode *)in);
	} else {
		g_warning("trying to close iconv i dont know about: %p", ip);
		iconv_close(ip);
	}
	UNLOCK();

}
Beispiel #8
0
/* This should run pretty quick, its called a lot */
iconv_t e_iconv_open(const char *oto, const char *ofrom)
{
	const char *to, *from;
	char *tofrom;
	struct _iconv_cache *ic;
	struct _iconv_cache_node *in;
	int errnosav;
	iconv_t ip;

	to = e_iconv_charset_name (oto);
	from = e_iconv_charset_name (ofrom);

	/* e_iconv_charset_name() could return NULL in case of invalid charset.
	   So, we need to check them here. */
	if (to == NULL || from == NULL) {
		errno = EINVAL;
		return (iconv_t) -1;
	}

	tofrom = g_alloca (strlen (to) + strlen (from) + 2);
	sprintf(tofrom, "%s%%%s", to, from);

	LOCK();

	ic = g_hash_table_lookup(iconv_cache, tofrom);
	if (ic) {
		e_dlist_remove((EDListNode *)ic);
	} else {
		struct _iconv_cache *last = (struct _iconv_cache *)iconv_cache_list.tailpred;
		struct _iconv_cache *prev;

		prev = last->prev;
		while (prev && iconv_cache_size > E_ICONV_CACHE_SIZE) {
			in = (struct _iconv_cache_node *)last->open.head;
			if (in->next && !in->busy) {
				cd(printf("Flushing iconv converter '%s'\n", last->conv));
				e_dlist_remove((EDListNode *)last);
				g_hash_table_remove(iconv_cache, last->conv);
				flush_entry(last);
				iconv_cache_size--;
			}
			last = prev;
			prev = last->prev;
		}

		iconv_cache_size++;
		
		ic = g_malloc(sizeof(*ic));
		e_dlist_init(&ic->open);
		ic->conv = g_strdup(tofrom);
		g_hash_table_insert(iconv_cache, ic->conv, ic);

		cd(printf("Creating iconv converter '%s'\n", ic->conv));
	}
	e_dlist_addhead(&iconv_cache_list, (EDListNode *)ic);

	/* If we have a free iconv, use it */
	in = (struct _iconv_cache_node *)ic->open.tailpred;
	if (in->prev && !in->busy) {
		cd(printf("using existing iconv converter '%s'\n", ic->conv));
		ip = in->ip;
		if (ip != (iconv_t)-1) {
			/* work around some broken iconv implementations 
			 * that die if the length arguments are NULL 
			 */
			size_t buggy_iconv_len = 0;
			char *buggy_iconv_buf = NULL;

			/* resets the converter */
			iconv(ip, &buggy_iconv_buf, &buggy_iconv_len, &buggy_iconv_buf, &buggy_iconv_len);
			in->busy = TRUE;
			e_dlist_remove((EDListNode *)in);
			e_dlist_addhead(&ic->open, (EDListNode *)in);
		}
	} else {
		cd(printf("creating new iconv converter '%s'\n", ic->conv));
		ip = iconv_open(to, from);
		in = g_malloc(sizeof(*in));
		in->ip = ip;
		in->parent = ic;
		e_dlist_addhead(&ic->open, (EDListNode *)in);
		if (ip != (iconv_t)-1) {
			g_hash_table_insert(iconv_cache_open, ip, in);
			in->busy = TRUE;
		} else {
			errnosav = errno;
			/* g_warning("Could not open converter for '%s' to '%s' charset", from, to); */
			in->busy = FALSE;
			errno = errnosav;
		}
	}

	UNLOCK();

	return ip;
}