cvs: /php3/functions imap.c

From: Date: Wed, 03 Nov 1999 16:02:04 +0000
Subject: cvs: /php3/functions imap.c
Groups: php.dev 
Request: Send a blank email to php-dev+get-12098@lists.php.net to get a copy of this message
askalski Wed Nov 3 11:02:04 1999 EDT Modified files: /php3/functions imap.c Log: more work on persistent imap connections Index: php3/functions/imap.c diff -u php3/functions/imap.c:1.71 php3/functions/imap.c:1.72 --- php3/functions/imap.c:1.71 Mon Nov 1 11:45:36 1999 +++ php3/functions/imap.c Wed Nov 3 11:02:03 1999 @@ -33,7 +33,7 @@ | Andrew Skalski <askalski@chek.com> | +----------------------------------------------------------------------+ */ -/* $Id: imap.c,v 1.71 1999/11/01 16:45:36 chagenbu Exp $ */ +/* $Id: imap.c,v 1.72 1999/11/03 16:02:03 askalski Exp $ */ #define IMAP41 @@ -100,8 +100,10 @@ MAILSTREAM *imap_stream; long flags; #ifdef OP_RELOGIN - /* AJS: busy flag for persistent connections */ - unsigned char busy; + /* AJS: busy flag for persistent connections, pointers for chaining */ + struct php3_imap_le_struct *next; + struct php3_imap_le_struct **prev; + char busy; #endif } pils; @@ -123,11 +125,11 @@ struct php3_imap_message_struct *next; } MESSAGELIST; -MAILSTREAM *mail_close_it (pils *imap_le_struct); +void mail_close_it (pils *imap_le_struct); #ifdef OP_RELOGIN /* AJS: close persistent connection */ -MAILSTREAM *mail_phalfclose_it (pils *imap_le_struct); -MAILSTREAM *mail_pclose_it (pils *imap_le_struct); +void mail_userlogout_it (pils *imap_le_struct); +void mail_nuke_chain (pils **headp); #endif /* @@ -224,8 +226,9 @@ */ int le_imap; #ifdef OP_RELOGIN -/* AJS: persistent connection type */ +/* AJS: persistent connection type, chain pointer type */ int le_pimap; +int le_pimapchain; #endif char imap_user[80]=""; char imap_password[80]=""; @@ -254,39 +257,39 @@ unsigned long status_quota_all; #endif -MAILSTREAM *mail_close_it (pils *imap_le_struct) +void +mail_close_it (pils *imap_le_struct) { - MAILSTREAM *ret; - ret = mail_close_full (imap_le_struct->imap_stream,imap_le_struct->flags); + mail_close_full (imap_le_struct->imap_stream,imap_le_struct->flags); efree(imap_le_struct); - return ret; } #ifdef OP_RELOGIN /* AJS: stream close functions for persistent connections */ -MAILSTREAM *mail_phalfclose_it (pils *imap_le_struct) +void +mail_userlogout_it (pils *imap_le_struct) { /* Close this user's session, putting the stream back * into AUTHENTICATE state. (Note that IMAP does not * support this behavior... yet) */ imap_le_struct->busy = 0; - return mail_close_full( - imap_le_struct->imap_stream, - imap_le_struct->flags | CL_HALF); + mail_close_full(imap_le_struct->imap_stream, + imap_le_struct->flags | CL_HALF); } -MAILSTREAM *mail_pclose_it (pils *imap_le_struct) +void +mail_nuke_chain (pils **headp) { - /* Standard stream close, except that the imap_le_struct - * is free()'d rather than efree()'d. - */ - MAILSTREAM *ret; - ret = mail_close_full( - imap_le_struct->imap_stream, - imap_le_struct->flags); - free(imap_le_struct); - return ret; + pils *node, *next; + + for (node = *headp; node; node = next) { + next = node->next; + mail_close(node->imap_stream); + free(node); + } + + free(headp); } #endif @@ -616,7 +619,8 @@ le_imap = register_list_destructors(mail_close_it,NULL); #ifdef OP_RELOGIN /* AJS: destructors for persistent connections */ - le_pimap = register_list_destructors(mail_phalfclose_it,mail_pclose_it); + le_pimap = register_list_destructors(mail_userlogout_it, NULL); + le_pimapchain = register_list_destructors(NULL, mail_nuke_chain); #endif return SUCCESS; } @@ -633,6 +637,8 @@ long cl_flags=NIL; #ifdef OP_RELOGIN NETMBX netmbx; + char *hashed_details = NULL; + int hashed_details_length = 0; #endif int ind; int myargc=ARG_COUNT(ht); @@ -668,85 +674,128 @@ } imap_stream = NIL; - le = NULL; if (persistent) { + list_entry *le = NULL; + list_entry new_le; + pils **headp, *node; + int need_update = 0; + + hashed_details_length = sizeof("imap_") + strlen(netmbx.host); + hashed_details = (char*) emalloc(hashed_details_length); + sprintf(hashed_details, "imap_%s", netmbx.host); + /* Check for an existing connection. */ - if ((_php3_hash_find( plist, - netmbx.host, - strlen(netmbx.host) + 1, - (void**) &le) == FAILURE) - || (le->type != le_pimap)) + if ( (_php3_hash_find(plist, + hashed_details, + hashed_details_length, + (void*) &le) == FAILURE) || + (le->type != le_pimapchain)) { le = NULL; } /* Re-use existing connection if available. */ + node = NULL; + headp = NULL; if (le) { - imap_le_struct = (pils*) le->ptr; - if (imap_le_struct->busy) { - /* This connection is in use right now. */ - le = NULL; - } - else { - /* Login with a new username/password. */ - imap_stream = mail_open( - imap_le_struct->imap_stream, - mailbox->value.str.val, - flags | OP_RELOGIN); - if (imap_stream) { - /* Ping the stream to see if it is - * still good. - */ - if (!mail_ping(imap_stream)) { - mail_close(imap_stream); - imap_stream = NIL; - } + headp = (pils**) le->ptr; + + /* find a non-busy connection */ + for (node=*headp; node; node=node->next) + if (!node->busy) + break; + } + + /* If we found a node, do a relogin. */ + if (node) { + imap_stream = mail_open( + node->imap_stream, + mailbox->value.str.val, + flags | OP_RELOGIN); + if (imap_stream) { + /* Ping the stream to see if it is + * still good. + */ + if (!mail_ping(imap_stream)) { + mail_close(imap_stream); + imap_stream = NIL; } } } - /* Did we find a valid stream? */ + /* Get a fresh stream if we don't have one yet. */ if (imap_stream == NIL) { /* Open a new connection. */ imap_stream = mail_open( NIL, mailbox->value.str.val, flags | OP_RELOGIN); - if (imap_stream == NIL) { - /* XXX if (le) { remove_from_hash; } */ - RETURN_FALSE; + } + + /* Do we have a stream yet? If not, bail. */ + if (imap_stream == NIL) { + if (node) { + /* unlink the node */ + if ((*node->prev = node->next)) + node->next->prev = node->prev; + free(node); + /* delete the hash entry if empty */ + if (*headp == NULL) + _php3_hash_del(plist, + hashed_details, + hashed_details_length); } + efree(hashed_details); + RETURN_FALSE; + } - if (le) { - /* Reuse existing hash entry. */ - imap_le_struct = (pils*) le->ptr; + /* Allocate a new node if none. */ + if (node == NULL) { + /* Alloc new hash entry. */ + node = malloc(sizeof(pils)); + if (node == NULL) { + efree(hashed_details); + RETURN_FALSE; } - else { - /* Alloc new hash entry. */ - imap_le_struct = malloc(sizeof(pils)); - new_le.type = le_pimap; - new_le.ptr = imap_le_struct; + + /* Allocate headp if it does not exist. */ + if (headp == NULL) { + headp = calloc(1, sizeof(*headp)); + need_update = 1; } + + node->prev = headp; + node->next = *headp; + *headp = node; } - /* Initialize the imap_le_struct */ - imap_le_struct->busy = 1; - imap_le_struct->imap_stream = imap_stream; - imap_le_struct->flags = cl_flags; - - /* Add to hash if not there already. */ - if (!le && _php3_hash_update( - plist, - netmbx.host, - strlen(netmbx.host) + 1, - (void*) &new_le, - sizeof(list_entry), - NULL) == FAILURE) + /* Initialize the node. */ + node->busy = 1; + node->imap_stream = imap_stream; + node->flags = cl_flags; + + /* Update the hash. */ + new_le.type = le_pimapchain; + new_le.ptr = headp; + if ( need_update && + _php3_hash_update(plist, hashed_details, + hashed_details_length, &new_le, + sizeof(new_le), NULL) == FAILURE) { - mail_close(imap_stream); - free(imap_le_struct); + /* unlink and free the new node */ + if ((*node->prev = node->next)) + node->next->prev = node->prev; + mail_close(node->imap_stream); + free(node); + + free(headp); + efree(hashed_details); RETURN_FALSE; } + + efree(hashed_details); + + imap_le_struct = node; } else { #endif

« previous php.dev (#12098) next »