sas             Sat Nov 30 22:47:50 2002 EDT

  Added files:                 
    /php4/ext/ircg      ircg_common.c php_ircg_alloc.h php_ircg_hash.h 
                        php_ircg_lock.h 

  Removed files:               
    /php4/ext/ircg      ircg_dummy.c 

  Modified files:              
    /php4/ext/ircg      config.m4 ircg.c ircg_thttpd.c php_ircg.h 
  Log:
  Initial work on porting extension to IRCG 4.
  
  
Index: php4/ext/ircg/config.m4
diff -u php4/ext/ircg/config.m4:1.15 php4/ext/ircg/config.m4:1.16
--- php4/ext/ircg/config.m4:1.15        Wed Nov 13 20:09:45 2002
+++ php4/ext/ircg/config.m4     Sat Nov 30 22:47:49 2002
@@ -1,5 +1,5 @@
 dnl
-dnl $Id: config.m4,v 1.15 2002/11/14 01:09:45 sas Exp $
+dnl $Id: config.m4,v 1.16 2002/12/01 03:47:49 sas Exp $
 dnl
 
 PHP_ARG_WITH(ircg, for IRCG support,
@@ -29,9 +29,9 @@
   PHP_NEW_EXTENSION(ircg, ircg.c ircg_scanner.c, $ext_shared)
   if test "$PHP_SAPI" = "thttpd"; then
     PHP_ADD_SOURCES(PHP_EXT_DIR(ircg),ircg_thttpd.c,[],sapi)
-    PHP_ADD_SOURCES(PHP_EXT_DIR(ircg),ircg_dummy.c,[],cli)
+    PHP_ADD_SOURCES(PHP_EXT_DIR(ircg),ircg_common.c,[],cli)
   else
-    PHP_ADD_SOURCES(PHP_EXT_DIR(ircg),ircg_dummy.c)
+    PHP_ADD_SOURCES(PHP_EXT_DIR(ircg),ircg_common.c)
   fi
   AC_DEFINE(HAVE_IRCG, 1, [Whether you want IRCG support])
   PHP_ADD_MAKEFILE_FRAGMENT
Index: php4/ext/ircg/ircg.c
diff -u php4/ext/ircg/ircg.c:1.143 php4/ext/ircg/ircg.c:1.144
--- php4/ext/ircg/ircg.c:1.143  Sun Nov 17 00:29:17 2002
+++ php4/ext/ircg/ircg.c        Sat Nov 30 22:47:49 2002
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: ircg.c,v 1.143 2002/11/17 05:29:17 sas Exp $ */
+/* $Id: ircg.c,v 1.144 2002/12/01 03:47:49 sas Exp $ */
 
 /* {{{ includes */
 
@@ -28,13 +28,17 @@
 #include "config.h"
 #endif
 
+/* for smart_strs */
+#define realloc(a,b) IRCG_SHARED_REALLOC(a,b)
+#define free(a) IRCG_SHARED_FREE(a)
+
 #include "php.h"
 #include "php_ini.h"
 #include "php_ircg.h"
 #include "ext/standard/html.h"
 
 #include "ext/standard/php_lcg.h"
-#include "ext/standard/php_smart_str.h"
+
 #include "ext/standard/info.h"
 #include "ext/standard/basic_functions.h"
 
@@ -61,15 +65,48 @@
 
 /* {{{ Definitions */
 
-/* This module is not intended for thread-safe use */
-
-static HashTable h_fd2irconn; /* fd's to Integer IDs */
+#if IRCG_API_VERSION < 20021127
+#define USE_IRCONN_MANAGEMENT
 static HashTable h_irconn; /* Integer IDs to php_irconn_t * */
-static HashTable h_fmt_msgs; /* Integer IDs to php_fmt_msgs_t * */ 
 static int irconn_id;
 
-static unsigned long irc_connects, irc_set_currents, irc_quit_handlers, 
-               exec_fmt_msgs, exec_token_compiler;
+#define USE_FD2IRCONN
+static HashTable h_fd2irconn; /* fd's to Integer IDs */
+
+
+/* provide dummy definitions */
+#include "php_ircg_hash.h"
+#include "php_ircg_alloc.h"
+#include "php_ircg_lock.h"
+
+#else
+#include <ircg_resource.h>
+#include <ircg_alloc.h>
+#include <ircg_hash.h>
+#include <ircg_lock.h>
+#endif
+
+#include "ext/standard/php_smart_str.h"
+
+static struct {
+       ircg_hash_table h_fmt_msgs;
+
+#define h_fmt_msgs php_ircg->h_fmt_msgs
+
+       /* these just serve statistical/entertainment purposes */
+       unsigned long irc_connects, irc_set_currents, irc_quit_handlers, 
+                       exec_fmt_msgs, exec_token_compiler;
+
+#define irc_connects  php_ircg->irc_connects
+#define irc_set_currents  php_ircg->irc_set_currents
+#define irc_quit_handlers  php_ircg->irc_quit_handlers
+#define exec_fmt_msgs  php_ircg->exec_fmt_msgs
+#define exec_token_compiler  php_ircg->exec_token_compiler
+
+
+       IRCG_LOCK(fmt_msgs_lock);
+#define fmt_msgs_lock php_ircg->fmt_msgs_lock
+} *php_ircg;
 
 /* }}} */
 
@@ -195,7 +232,7 @@
 #endif
        php_fmt_msgs_t *fmt_msgs;
        irc_write_buf wb;
-       HashTable ctcp_msgs;
+       ircg_hash_table ctcp_msgs;
        
 #ifdef IRCG_PENDING_URL
        char *od_data; /* On_Die */
@@ -243,8 +280,6 @@
 
 static void msg_send(php_irconn_t *conn, smart_str *msg);
 
-static php_irconn_t *flush_data;
-
 /* }}} */
 
 /* {{{ Default format messages */
@@ -263,9 +298,9 @@
        "",
        "%f changes nick to %t<br />",
        "%f quits (%m)<br />",
-       "Welcome to channel %c:",
+       "Users in channel %c:",
        " %f",
-       " in this very fine channel %c",
+       " in the channel %c<br />",
        "%f: user(%t) host(%c) real name(%m)<br />",
        "%f: server(%c) server info(%m)<br />",
        "%f has been idle for %m seconds<br />",
@@ -284,6 +319,8 @@
        "%f is inviting %t to %c<br />",
 };
 
+ZEND_DECLARE_MODULE_GLOBALS(ircg)
+
 /* }}} */
 
 /* {{{ Format-message accessor macros */
@@ -307,16 +344,29 @@
 {
        php_irconn_t **ret;
 
-       if (zend_hash_index_find(&h_irconn, id, (void **) &ret) == FAILURE)
+#ifdef USE_IRCONN_MANAGEMENT
+       if (ircg_hash_index_find(&h_irconn, id, (void **) &ret) == FAILURE)
                return NULL;
        return *ret;
+#else
+       return ircg_resource_get(id);
+#endif
 }
 
+#ifdef USE_IRCONN_MANAGEMENT
+#define put_irconn(a) do {} while(0)
+#else
+static void put_irconn(php_irconn_t *c)
+{
+       ircg_resource_put(c->irconn_id);
+}
+#endif
+
 static php_fmt_msgs_t *lookup_fmt_msgs(zval **id)
 {
        php_fmt_msgs_t *ret;
 
-       if (zend_hash_find(&h_fmt_msgs, Z_STRVAL_PP(id), Z_STRLEN_PP(id), (void **) 
&ret) == FAILURE)
+       if (ircg_hash_find(&h_fmt_msgs, Z_STRVAL_PP(id), Z_STRLEN_PP(id), (void **) 
+&ret) == FAILURE)
                return NULL;
        return ret;
 }
@@ -336,13 +386,13 @@
                switch (f->t[i].code) {
                case C_STRING: 
                        smart_str_free_ex(f->t[i].para.ptr, 1);
-                       free(f->t[i].para.ptr); 
+                       IRCG_SHARED_FREE(f->t[i].para.ptr); 
                        break;
                }
                i++;
        }
 
-       free(f->t);
+       IRCG_SHARED_FREE(f->t);
 }
 
 static void fmt_msgs_dtor(void *dummy)
@@ -387,11 +437,13 @@
 
        irc_quit_handlers++;
        if (conn->fd > -1) {
-               zend_hash_index_del(&h_fd2irconn, conn->fd);
-               if (conn->file_fd == -1)
-                       irc_write_buf_del(&conn->wb);
+#ifdef USE_FD2IRCONN
+               ircg_hash_index_del(&h_fd2irconn, conn->fd);
                if (is_my_conn(conn))
                        shutdown(conn->fd, 2);
+#endif
+               if (conn->file_fd == -1)
+                       irc_write_buf_del(&conn->wb);
        }
        if (conn->file_fd != -1) {
                smart_str m = {0};
@@ -405,19 +457,22 @@
        }
                
        conn->fd = -2;
-       zend_hash_index_del(&h_irconn, conn->irconn_id);
 
-       zend_hash_destroy(&conn->ctcp_msgs);
+#ifdef USE_IRCONN_MANAGEMENT
+       ircg_hash_index_del(&h_irconn, conn->irconn_id);
+#endif
+       
+       ircg_hash_destroy(&conn->ctcp_msgs);
        smart_str_free_ex(&conn->buffer, 1);
        
 #ifdef IRCG_PENDING_URL
        if (conn->od_port) {
                irc_add_pending_url(conn->od_ip, conn->od_port, conn->od_data, 
conn->od_len);
-               free(conn->od_data);
+               IRCG_SHARED_FREE(conn->od_data);
        }
 #endif
        
-       free(conn);
+       IRCG_SHARED_FREE(conn);
 }
 /* }}} */
 
@@ -559,7 +614,7 @@
 
 /* {{{ token_compiler */
 
-#define NEW_TOKEN(a, b) t = realloc(t, sizeof(token_t) * (++n)); t[n-1].code=a; 
t[n-1].para.b
+#define NEW_TOKEN(a, b) t = IRCG_SHARED_REALLOC(t, sizeof(token_t) * (++n)); 
+t[n-1].code=a; t[n-1].para.b
 
 static void token_compiler(const char *fmt, format_msg_t *f)
 {
@@ -587,7 +642,7 @@
                q = p;
                while (*q != '%') 
                        if (++q >= pe) {
-                               s = malloc(sizeof *s);
+                               s = IRCG_SHARED_ALLOC(sizeof *s);
                                s->c = 0;
                                smart_str_appendl_ex(s, p, pe - p, 1);
                                NEW_TOKEN(C_STRING, ptr) = s;
@@ -596,7 +651,7 @@
                len = q - p;
 
                if (len > 0) {
-                       s = malloc(sizeof *s);
+                       s = IRCG_SHARED_ALLOC(sizeof *s);
                        s->c = 0;
                        smart_str_appendl_ex(s, p, len, 1);
                        NEW_TOKEN(C_STRING, ptr) = s;
@@ -733,31 +788,34 @@
 
 #define ADD_HEADER(a) sapi_add_header(a, sizeof(a) - 1, 1)
 
+#ifdef USE_FD2IRCONN
 static void http_closed_connection(int fd)
 {
        int *id, stored_id;
 
-       if (zend_hash_index_find(&h_fd2irconn, fd, (void **) &id) == FAILURE)
+       if (ircg_hash_index_find(&h_fd2irconn, fd, (void **) &id) == FAILURE)
                return;
 
        stored_id = *id;
 
-       zend_hash_index_del(&h_fd2irconn, fd);
-       zend_hash_index_del(&h_irconn, stored_id);
+       ircg_hash_index_del(&h_fd2irconn, fd);
+#ifdef USE_IRCONN_MANAGEMENT
+       ircg_hash_index_del(&h_irconn, stored_id);
+#endif
 }
+#endif
 
 /* }}} */
 
-static time_t ircg_now(void)
+static time_t php_ircg_now(void)
 {
        struct timeval now;
 
 #if IRCG_API_VERSION >= 20010601
-       if (ircg_now_time_t != (time_t) 0) 
-               return ircg_now_time_t;
-       else
+       now.tv_sec = ircg_now_time_t;
+       if (now.tv_sec == (time_t) 0) 
 #endif
-       gettimeofday(&now, NULL);
+               gettimeofday(&now, NULL);
 
        return now.tv_sec;
 }
@@ -783,7 +841,7 @@
        case -2: /* Connection was finished */
                goto done;
        case -1: /* No message window yet. Buffer */
-               if ((ircg_now() - conn->login) > WINDOW_TIMEOUT) {
+               if ((php_ircg_now() - conn->login) > WINDOW_TIMEOUT) {
                        irc_disconnect(&conn->conn, timeout_message);
                        goto done;
                }
@@ -871,7 +929,7 @@
                        *real_msg_end = '\0';
                        *token_end = '\0';
                        
-                       if (zend_hash_find(&conn->ctcp_msgs, msg->c + 1, token_end - 
msg->c - 1, (void **) &fmt_msg) != SUCCESS) {
+                       if (ircg_hash_find(&conn->ctcp_msgs, msg->c + 1, token_end - 
+msg->c - 1, (void **) &fmt_msg) != SUCCESS) {
                                return;
                        }
 
@@ -1094,7 +1152,7 @@
 static void error_msg_dtor(struct errormsg *m)
 {
        smart_str_free_ex(&m->msg, 1);
-       free(m);
+       IRCG_SHARED_FREE(m);
 }
 
 static void error_msg_gc(time_t now)
@@ -1138,12 +1196,12 @@
        }
 
        if (!m) {
-               m = malloc(sizeof(*m));
+               m = IRCG_SHARED_ALLOC(sizeof(*m));
                m->msg.c = 0;
                m->id = conn->irconn_id;
        }
 
-       m->when = ircg_now();
+       m->when = php_ircg_now();
        m->msg.len = 0;
        smart_str_append_ex(&m->msg, msg, 1);
        m->msgid = msgid;
@@ -1318,13 +1376,19 @@
 {
        php_irconn_t *conn = dummy;
 
-       if (conn->fd >= 0)
-               send(conn->fd, "  ", 2, 0);
-       else if (conn->file_fd < 0 && (ircg_now() - conn->login) > WINDOW_TIMEOUT) {
+       
+       if (conn->fd >= 0) {
+               smart_str tmp = {0};
+
+               smart_str_setl(&tmp, "  ", 2);
+               irc_write_buf_append_ex(&conn->wb, &tmp, 1);
+       } else if (conn->file_fd < 0 
+                       && (php_ircg_now() - conn->login) > WINDOW_TIMEOUT) {
                char buf[1024];
 
-               sprintf(buf, "timeout after %d seconds (%d, %d)", 
ircg_now()-conn->login,
-                               ircg_now(), conn->login);
+               sprintf(buf, "timeout after %d seconds (%d, %d)", 
+                               php_ircg_now()-conn->login,
+                               php_ircg_now(), conn->login);
                irc_disconnect(ircc, buf);
        }
 }
@@ -1389,15 +1453,17 @@
        convert_to_long_ex(p3);
        convert_to_string_ex(p4);
 
-       if (inet_aton(Z_STRVAL_PP(p2), &conn->od_ip) == 0)
-               RETURN_FALSE;
-
-       conn->od_port = Z_LVAL_PP(p3);
-       conn->od_data = malloc(Z_STRLEN_PP(p4));
-       memcpy(conn->od_data, Z_STRVAL_PP(p4), Z_STRLEN_PP(p4));
-       conn->od_len = Z_STRLEN_PP(p4);
-
-       RETURN_TRUE;
+       if (inet_aton(Z_STRVAL_PP(p2), &conn->od_ip) != 0) {
+               conn->od_port = Z_LVAL_PP(p3);
+               conn->od_data = IRCG_SHARED_ALLOC(Z_STRLEN_PP(p4));
+               memcpy(conn->od_data, Z_STRVAL_PP(p4), Z_STRLEN_PP(p4));
+               conn->od_len = Z_STRLEN_PP(p4);
+               RETVAL_TRUE;
+       } else {
+               RETVAL_FALSE;
+       }
+       
+       put_irconn(conn);
 }
 #endif
 /* }}} */
@@ -1419,6 +1485,8 @@
        if (!conn) RETURN_FALSE;
 
        RETVAL_STRINGL((char *) conn->conn.username, conn->conn.username_len, 1);
+
+       put_irconn(conn);
 }
 /* }}} */
 
@@ -1441,28 +1509,29 @@
 
        if (conn->fd != -1) {
                php_error(E_WARNING, "%s(): Called after a call to ircg_set_current(). 
You must set the output filename before opening the persistent HTTP connection which 
is kept alive.", get_active_function_name(TSRMLS_C));
-               RETURN_FALSE;
-       }
+               RETVAL_FALSE;
+       } else {
+               if (conn->file_fd != -1) 
+                       close(conn->file_fd);
 
-       if (conn->file_fd != -1) 
-               close(conn->file_fd);
-       
-       conn->file_fd = open(Z_STRVAL_PP(p2), O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, 
0644);
-       if (conn->file_fd == -1) {
-               RETURN_FALSE;
-       }
-       
+               conn->file_fd = open(Z_STRVAL_PP(p2), O_WRONLY | O_CREAT | O_TRUNC | 
+O_APPEND, 0644);
+               if (conn->file_fd == -1) {
+                       RETVAL_FALSE;
+               } else {
 #ifdef F_SETFD
-       if (fcntl(conn->file_fd, F_SETFD, 1)) {
-               close(conn->file_fd);
-               conn->file_fd = -1;
-               RETURN_FALSE;
-       }
+                       if (fcntl(conn->file_fd, F_SETFD, 1)) {
+                               close(conn->file_fd);
+                               conn->file_fd = -1;
+                               RETVAL_FALSE;
+                       } else
 #endif
-       
-       msg_replay_buffer(conn);
-
-       RETURN_TRUE;
+                       {
+                               msg_replay_buffer(conn);
+                               RETVAL_TRUE;
+                       }
+               }
+       }
+       put_irconn(conn);
 }
 /* }}} */
 
@@ -1472,9 +1541,6 @@
 {
        zval **p1;
        php_irconn_t *conn;
-#if 0
-       socklen_t len = sizeof(struct sockaddr_in);
-#endif
 
        if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &p1) == FAILURE)
                WRONG_PARAM_COUNT;
@@ -1486,36 +1552,38 @@
        if (!conn) RETURN_FALSE;
 
        if (conn->fd >= 0) {
+#ifdef USE_FD2IRCONN
                /* There is a HTTP connection alive, kill it */
-               zend_hash_index_del(&h_fd2irconn, conn->fd);
+               ircg_hash_index_del(&h_fd2irconn, conn->fd);
+#endif
                if (conn->file_fd == -1)
                        irc_write_buf_del(&conn->wb);
-               if (is_my_conn(conn))
-                       shutdown(conn->fd, 2);
+               conn->fd = -1;
        }
 
-#if 0
-       /* store peer information for safe shutdown */
-       if (getpeername(conn->fd, &conn->sin, &len) == -1) {
-               php_error(E_WARNING, "getpeername failed: %d (%s)", errno, 
strerror(errno));
-       }
-#endif
-
        irc_set_currents++;
-
-       if (php_ircg_register_with_sapi(&conn->fd, http_closed_connection) 
+       
+       if (php_ircg_register_with_sapi(&conn->fd TSRMLS_CC) 
+#ifdef USE_FD2IRCONN
+                       || php_ircg_register_closed_connection(http_closed_connection)
+#endif
                        || fcntl(conn->fd, F_GETFL) == -1) {
-               zend_hash_index_del(&h_irconn, Z_LVAL_PP(p1));
+#ifdef USE_IRCONN_MANAGEMENT
+               ircg_hash_index_del(&h_irconn, Z_LVAL_PP(p1));
+#endif
                php_error(E_WARNING, "current fd is not valid");
-               RETURN_FALSE;
-       }
-       zend_hash_index_update(&h_fd2irconn, conn->fd, &Z_LVAL_PP(p1), sizeof(int), 
NULL);
-       if (conn->file_fd == -1) {
-               flush_data = conn;
-               irc_write_buf_add(&conn->wb, conn->fd);
+               RETVAL_FALSE;
+       } else {
+#ifdef USE_FD2IRCONN
+               ircg_hash_index_update(&h_fd2irconn, conn->fd, &Z_LVAL_PP(p1), 
+                               sizeof(int), NULL);
+#endif
+               if (conn->file_fd == -1 && conn->fd >= 0) {
+                       IRCGG(flush_data) = conn;
+               }
+               RETVAL_TRUE;
        }
-
-       RETURN_TRUE;
+       put_irconn(conn);
 }
 /* }}} */
 
@@ -1593,6 +1661,8 @@
        
        irc_join(&conn->conn, Z_STRVAL_PP(p2), key,  conn);
 
+       put_irconn(conn);
+
        RETVAL_TRUE;
 }
 /* }}} */
@@ -1616,6 +1686,8 @@
        if (!conn) RETURN_FALSE;
        
        irc_handle_command(&conn->conn, "WHOIS", 1, Z_STRVAL_PP(p2));
+
+       put_irconn(conn);
        RETVAL_TRUE;
 }
 #endif
@@ -1642,6 +1714,8 @@
        smart_str_setl(&s, Z_STRVAL_PP(args[1]), Z_STRLEN_PP(args[1]));
        if (irc_ignore_check(&conn->conn, &s) == 0)
                irc_ignore_add(&conn->conn, &s, 1);
+
+       put_irconn(conn);
 }
 #endif
 /* }}} */
@@ -1688,9 +1762,12 @@
        if (!conn) RETURN_FALSE;
 
        smart_str_setl(&s, Z_STRVAL_PP(args[1]), Z_STRLEN_PP(args[1]));
-       if (irc_ignore_del(&conn->conn, &s))
-               RETURN_FALSE;
-       RETURN_TRUE;
+       if (irc_ignore_del(&conn->conn, &s)) {
+               RETVAL_FALSE;
+       } else {
+               RETVAL_TRUE;
+       }
+       put_irconn(conn);
 }
 #endif
 /* }}} */
@@ -1716,6 +1793,7 @@
        
        irc_handle_command(&conn->conn, "MODE", 3, Z_STRVAL_PP(args[1]),
                        Z_STRVAL_PP(args[2]), Z_STRVAL_PP(args[3]));
+       put_irconn(conn);
        RETVAL_TRUE;
 }
 #endif
@@ -1741,6 +1819,7 @@
        if (!conn) RETURN_FALSE;
        
        irc_handle_command(&conn->conn, "TOPIC", 2, Z_STRVAL_PP(p2), Z_STRVAL_PP(p3));
+       put_irconn(conn);
        RETVAL_TRUE;
 }
 #endif
@@ -1804,6 +1883,8 @@
        if (!conn) RETURN_FALSE;
 
        irc_handle_command(&conn->conn, "WHO", ops ? 2 : 1, Z_STRVAL_PP(p2), "o");
+
+       put_irconn(conn);
        
        RETVAL_TRUE;
 }
@@ -1832,6 +1913,7 @@
 
        irc_handle_command(&conn->conn, "INVITE", 2, Z_STRVAL_PP(p3),
                        Z_STRVAL_PP(p2));
+       put_irconn(conn);
        
        RETVAL_TRUE;
 }
@@ -1859,6 +1941,7 @@
        if (!conn) RETURN_FALSE;
        
        irc_handle_command(&conn->conn, "KICK", 3, Z_STRVAL_PP(p2), Z_STRVAL_PP(p3), 
Z_STRVAL_PP(p4));
+       put_irconn(conn);
        RETVAL_TRUE;
 }
 #endif
@@ -1882,6 +1965,7 @@
        if (!conn) RETURN_FALSE;
        
        irc_part(&conn->conn, Z_STRVAL_PP(p2));
+       put_irconn(conn);
        RETVAL_TRUE;
 }
 /* }}} */
@@ -1891,15 +1975,17 @@
 PHP_FUNCTION(ircg_is_conn_alive)
 {
        zval **p1;
-
+       php_irconn_t *conn;
+       
        if (ZEND_NUM_ARGS() != 1
                        || zend_get_parameters_ex(1, &p1) == FAILURE)
                WRONG_PARAM_COUNT;
 
        convert_to_long_ex(p1);
 
-       if (lookup_irconn(Z_LVAL_PP(p1)))
+       if ((conn = lookup_irconn(Z_LVAL_PP(p1))))
                RETURN_TRUE;
+       put_irconn(conn);
        RETURN_FALSE;
 }
 /* }}} */
@@ -1953,10 +2039,12 @@
                        token_compiler("", &fmt_msgs.fmt_msgs[i]);
        }
 
-       
-       zend_hash_update(&h_fmt_msgs, Z_STRVAL_PP(p1), Z_STRLEN_PP(p1), 
+       IRCG_LOCK_GET(fmt_msgs_lock);
+       ircg_hash_update(&h_fmt_msgs, Z_STRVAL_PP(p1), Z_STRLEN_PP(p1), 
                &fmt_msgs, sizeof(fmt_msgs), NULL);
 
+       IRCG_LOCK_PUT(fmt_msgs_lock);
+       
        RETVAL_TRUE;    
 }
 /* }}} */
@@ -2069,7 +2157,7 @@
                zend_hash_get_current_data_ex(Z_ARRVAL_PP(array), (void **) &val, 
&pos);
                convert_to_string_ex(val);
                token_compiler(Z_STRVAL_PP(val), &fmt);
-               zend_hash_add(&conn->ctcp_msgs, str, str_len - 1, &fmt,
+               ircg_hash_add(&conn->ctcp_msgs, str, str_len - 1, &fmt,
                                sizeof(fmt), NULL);
                
                zend_hash_move_forward_ex(Z_ARRVAL_PP(array), &pos);
@@ -2123,7 +2211,7 @@
         * conn must be able to live longer than the hash entry in h_irconn,
         * so we have to allocate it ourselves.
         */
-       conn = malloc(sizeof(*conn));
+       conn = IRCG_SHARED_ALLOC(sizeof(*conn));
        conn->fd = conn->file_fd = -1;
        conn->ident = conn->password = conn->realname = NULL;
        if (ZEND_NUM_ARGS() > 5 && Z_TYPE_PP(p6) == IS_ARRAY) {
@@ -2154,34 +2242,40 @@
        conn->fmt_msgs = fmt_msgs;      
        if (irc_connect(username, register_hooks, 
                        conn, server, port, &conn->conn)) {
-               free(conn);
+               IRCG_SHARED_FREE(conn);
                RETURN_FALSE;
        }
        irc_connects++;
-       zend_hash_init(&conn->ctcp_msgs, 10, NULL, (dtor_func_t) ctcp_msgs_dtor, 1);
+       ircg_hash_init(&conn->ctcp_msgs, 10, NULL, (dtor_func_t) ctcp_msgs_dtor, 1);
        if (p5 && Z_TYPE_PP(p5) == IS_ARRAY) {
                ircg_copy_ctcp_msgs(p5, conn);
        }
        conn->password = conn->ident = NULL;
+
+#ifdef USE_IRCONN_MANAGEMENT
        if (irconn_id == 0)
                irconn_id = 10000.0 * php_combined_lcg(TSRMLS_C);
        else
                irconn_id += 20.0 * (1.0 + php_combined_lcg(TSRMLS_C));
        
        
-       while (zend_hash_index_exists(&h_irconn, irconn_id)) {
+       while (ircg_hash_index_exists(&h_irconn, irconn_id)) {
                irconn_id++;
        }
        
        conn->irconn_id = irconn_id;
-       zend_hash_index_update(&h_irconn, irconn_id, &conn, sizeof(conn), NULL);
+       ircg_hash_index_update(&h_irconn, irconn_id, &conn, sizeof(conn), NULL);
+#else
+       conn->irconn_id = conn->conn.resid;
+#endif
+
        conn->buffer.c = NULL;
-       conn->login = ircg_now();
+       conn->login = php_ircg_now();
                
        if (conn->login >= next_gc)
                error_msg_gc(conn->login);
 
-       RETVAL_LONG(irconn_id);
+       RETVAL_LONG(conn->irconn_id);
 }
 /* }}} */
 
@@ -2197,7 +2291,9 @@
        convert_to_long_ex(id);
        convert_to_string_ex(reason);
 
-       zend_hash_index_del(&h_irconn, Z_LVAL_PP(id));
+#ifdef USE_IRCONN_MANAGEMENT
+       ircg_hash_index_del(&h_irconn, Z_LVAL_PP(id));
+#endif
 
        RETURN_TRUE;
 }
@@ -2221,6 +2317,7 @@
        if (!conn) RETURN_FALSE;
        
        irc_nick(&conn->conn, Z_STRVAL_PP(newnick));
+       put_irconn(conn);
        
        RETURN_TRUE;
 }
@@ -2245,6 +2342,7 @@
        if (!conn) RETURN_FALSE;
 
        irc_handle_command(&conn->conn, "NOTICE", 2, Z_STRVAL_PP(recipient), 
Z_STRVAL_PP(msg));
+       put_irconn(conn);
        RETURN_TRUE;
 }
 /* }}} */
@@ -2418,21 +2516,47 @@
                msg_send(conn, &m);
        }
 
+       put_irconn(conn);
        RETURN_TRUE;
 }
 /* }}} */
 
+PHP_RINIT_FUNCTION(ircg)
+{
+       IRCGG(flush_data) = 0;
+}
+
 /* {{{ PHP_RSHUTDOWN
  */
 PHP_RSHUTDOWN_FUNCTION(ircg)
 {
-       if (flush_data) {
-               php_irconn_t *conn = flush_data;
+       if (IRCGG(flush_data)) {
+               php_irconn_t *conn = IRCGG(flush_data);
+
+               irc_write_buf_add(&conn->wb, conn->fd);
+
+#if IRCG_API_VERSION >= 20021127
+
+               /*
+                * In a multi-process environment, IRCG will use sendmsg(2)
+                * to send the socket to the control process.  After that
+                * system call, we can close the socket without any problem.
+                *
+                * Some web servers (e.g. Apache) will call shutdown(2) on
+                * the socket, so that the control process could not send
+                * any more data.  This must be prevented, so we 
+                * relinquish this process's control of the socket.
+                */
+               
+               if (irc_write_buf_close_conn()) {
+                       sapi_send_headers();
+                       sapi_flush();
+                       close(conn->fd);
+               }
+#endif
 
                msg_replay_buffer(conn);
                irc_write_buf_flush(&conn->wb);
-               
-               flush_data = NULL;
        }
 
        return SUCCESS;
@@ -2446,7 +2570,7 @@
        ircg_functions,
        PHP_MINIT(ircg),
        PHP_MSHUTDOWN(ircg),
-       NULL,
+       PHP_RINIT(ircg),
        PHP_RSHUTDOWN(ircg),
        PHP_MINFO(ircg),
        NO_VERSION_YET,
@@ -2458,12 +2582,26 @@
 #endif
 /* }}} */
 
+static void setup(int stage)
+{
+       if (stage == 0) {
+               int i;
+
+               php_ircg = IRCG_SHARED_ALLOC(sizeof *php_ircg);
+               memset(php_ircg, 0, sizeof *php_ircg);
+       
+               IRCG_LOCK_INIT(fmt_msgs_lock);
+
+               for (i = 0; i < NO_FMTS; i++) {
+                       token_compiler(fmt_msgs_default[i], 
+&fmt_msgs_default_compiled.fmt_msgs[i]);
+               }
+       }
+}
+
 /* {{{ PHP_MINIT_FUNCTION
  */
 PHP_MINIT_FUNCTION(ircg)
 {
-       int i;
-
 #if IRCG_API_VERSION >= 20010307
        if (irc_sizeof_irconn() != sizeof(irconn_t)) {
                printf("FATAL: The size of the irconn_t structure has changed "
@@ -2480,13 +2618,20 @@
        }
 #endif
        
-       for (i = 0; i < NO_FMTS; i++) {
-               token_compiler(fmt_msgs_default[i], 
&fmt_msgs_default_compiled.fmt_msgs[i]);
-       }
-
-       zend_hash_init(&h_fmt_msgs, 0, NULL, fmt_msgs_dtor, 1); 
-       zend_hash_init(&h_fd2irconn, 0, NULL, NULL, 1);
-       zend_hash_init(&h_irconn, 0, NULL, irconn_dtor, 1);
+#if IRCG_API_VERSION >= 20021127
+       ircg_setup_global("/tmp/ircg.lock", 0, setup);
+#else
+       setup(0);
+       setup(1);
+#endif
+       
+       ircg_hash_init(&h_fmt_msgs, 0, NULL, fmt_msgs_dtor, 1);
+#ifdef USE_FD2IRCONN   
+       ircg_hash_init(&h_fd2irconn, 0, NULL, NULL, 1);
+#endif
+#ifdef USE_IRCONN_MANAGEMENT
+       ircg_hash_init(&h_irconn, 0, NULL, irconn_dtor, 1);
+#endif
        return SUCCESS;
 }
 /* }}} */
@@ -2495,9 +2640,18 @@
  */
 PHP_MSHUTDOWN_FUNCTION(ircg)
 {
-       zend_hash_destroy(&h_fmt_msgs); 
-       zend_hash_destroy(&h_irconn);
-       zend_hash_destroy(&h_fd2irconn);
+       ircg_hash_destroy(&h_fmt_msgs);
+#ifdef USE_IRCONN_MANAGEMENT
+       ircg_hash_destroy(&h_irconn);
+#endif
+#ifdef USE_FD2IRCONN
+       ircg_hash_destroy(&h_fd2irconn);
+#endif
+
+       IRCG_LOCK_DESTROY(fmt_msgs_lock);
+
+       ircg_shutdown_global();
+       
        return SUCCESS;
 }
 /* }}} */
Index: php4/ext/ircg/ircg_thttpd.c
diff -u php4/ext/ircg/ircg_thttpd.c:1.1 php4/ext/ircg/ircg_thttpd.c:1.2
--- php4/ext/ircg/ircg_thttpd.c:1.1     Wed Nov 13 20:09:46 2002
+++ php4/ext/ircg/ircg_thttpd.c Sat Nov 30 22:47:49 2002
@@ -16,14 +16,16 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: ircg_thttpd.c,v 1.1 2002/11/14 01:09:46 sas Exp $ */
+/* $Id: ircg_thttpd.c,v 1.2 2002/12/01 03:47:49 sas Exp $ */
 
-
-int php_ircg_register_with_sapi(int *fd, void (*http_closed_connection)(int))
+int php_ircg_register_closed_connection(void (*http_closed_connection)(int))
 {
        thttpd_register_on_close(http_closed_connection);
        thttpd_set_dont_close();
-       *fd = thttpd_get_fd();
-
        return 0;
+}
+
+int php_ircg_register_with_sapi(int *fd TSRMLS_DC)
+{
+       return sapi_get_fd(fd TSRMLS_CC);
 }
Index: php4/ext/ircg/php_ircg.h
diff -u php4/ext/ircg/php_ircg.h:1.22 php4/ext/ircg/php_ircg.h:1.23
--- php4/ext/ircg/php_ircg.h:1.22       Sun Nov 17 00:29:17 2002
+++ php4/ext/ircg/php_ircg.h    Sat Nov 30 22:47:49 2002
@@ -65,14 +65,9 @@
 
 PHP_FUNCTION(confirm_ircg_compiled);   /* For testing, remove later. */
 
-/* 
-       Declare any global variables you may need between the BEGIN
-       and END macros here:     
-
 ZEND_BEGIN_MODULE_GLOBALS(ircg)
-       int global_variable;
+       void *flush_data;
 ZEND_END_MODULE_GLOBALS(ircg)
-*/
 
 /* In every function that needs to use variables in php_ircg_globals,
    do call IRCGLS_FETCH(); after declaring other variables used by

Index: php4/ext/ircg/ircg_common.c
+++ php4/ext/ircg/ircg_common.c
/*
   +----------------------------------------------------------------------+
   | PHP Version 4                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2002 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.02 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available at through the world-wide-web at                           |
   | http://www.php.net/license/2_02.txt.                                 |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | [EMAIL PROTECTED] so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Sascha Schumann <[EMAIL PROTECTED]>                         |
   +----------------------------------------------------------------------+
*/

/* $Id: ircg_common.c,v 1.1 2002/12/01 03:47:49 sas Exp $ */

#include "php.h"

int php_ircg_register_closed_connection(void (*http_closed_connection)(int))
{
        return -1;
}

int php_ircg_register_with_sapi(int *fd TSRMLS_DC)
{
        sapi_force_http_10(TSRMLS_C);
        return sapi_get_fd(fd TSRMLS_CC);
}

Index: php4/ext/ircg/php_ircg_alloc.h
+++ php4/ext/ircg/php_ircg_alloc.h

#define IRCG_SHARED_ALLOC(a) malloc((a))
#define IRCG_SHARED_REALLOC(a,b) realloc((a),(b))
#define IRCG_SHARED_FREE(a) free((a))


Index: php4/ext/ircg/php_ircg_hash.h
+++ php4/ext/ircg/php_ircg_hash.h

typedef HashTable ircg_hash_table;
#define ircg_hash_index_find zend_hash_index_find
#define ircg_hash_find zend_hash_find
#define ircg_hash_index_del zend_hash_index_del
#define ircg_hash_update zend_hash_update
#define ircg_hash_internal_pointer_reset_ex zend_hash_internal_pointer_reset_ex
#define ircg_hash_get_current_key_ex zend_hash_get_current_key_ex
#define ircg_hash_get_current_data_ex zend_hash_get_current_data_ex
#define ircg_hash_add zend_hash_add
#define ircg_hash_move_forward_ex zend_hash_move_forward_ex
#define ircg_hash_init zend_hash_init
#define ircg_hash_destroy zend_hash_destroy
#define ircg_hash_index_update zend_hash_index_update
#define ircg_hash_index_exists zend_hash_index_exists

Index: php4/ext/ircg/php_ircg_lock.h
+++ php4/ext/ircg/php_ircg_lock.h
#define IRCG_LOCK(name) char dummy_ ## name
#define IRCG_LOCK_INIT(name) do {} while (0)
#define IRCG_LOCK_GET(name) do {} while (0)
#define IRCG_LOCK_PUT(name) do {} while (0)
#define IRCG_LOCK_DESTROY(name) do {} while (0)

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to