cvs: /php3/functions imap.c
| From: | Andrew Skalski | 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