Re: cvs: /php3/functions imap.c
| From: | Thies C. Arntzen | Date: | Wed, 03 Nov 1999 18:01:25 +0000 |
| Subject: | Re: cvs: /php3/functions imap.c | ||
| References: | 1 | Groups: | php.dev |
| Request: | Send a blank email to php-dev+get-12100@lists.php.net to get a copy of this message | ||
andrew,
please don't break anything - we had planned to release 3.0.13 tomorrow...
tc
On Wed, 3 Nov 1999, Andrew Skalski wrote:
> 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
>
>
>
> --
> PHP Development Mailing List <http://www.php.net/>
> To unsubscribe, e-mail: php-dev-unsubscribe@lists.php.net
> For additional commands, e-mail: php-dev-help@lists.php.net
> To contact the list administrators, e-mail: php-list-admin@lists.php.net
>
>
Thies C. Arntzen "One Big-Mac, Small Fries and a Coke!"
Digital Collections Phone +49 40 235350 Fax +49 40 23535180
Hammerbrookstr. 93 20097 Hamburg / Germany