Index: pjproject/trunk/pjlib/src/pj/ioqueue_epoll.c
===================================================================
--- pjproject/trunk/pjlib/src/pj/ioqueue_epoll.c	(revision 590)
+++ pjproject/trunk/pjlib/src/pj/ioqueue_epoll.c	(revision 592)
@@ -142,6 +142,6 @@
 #define THIS_FILE   "ioq_epoll"
 
-#define TRACE_(expr) PJ_LOG(3,expr)
-//#define TRACE_(expr)
+//#define TRACE_(expr) PJ_LOG(3,expr)
+#define TRACE_(expr)
 
 /*
@@ -156,4 +156,10 @@
 {
     DECLARE_COMMON_KEY
+};
+
+struct queue
+{
+    pj_ioqueue_key_t	    *key;
+    enum ioqueue_event_type  event_type;
 };
 
@@ -168,4 +174,6 @@
     pj_ioqueue_key_t	hlist;
     int			epfd;
+    struct epoll_event *events;
+    struct queue       *queue;
 };
 
@@ -230,4 +238,10 @@
     }
     
+    ioqueue->events = pj_pool_calloc(pool, max_fd, sizeof(struct epoll_event));
+    PJ_ASSERT_RETURN(ioqueue->events != NULL, PJ_ENOMEM);
+
+    ioqueue->queue = pj_pool_calloc(pool, max_fd, sizeof(struct queue));
+    PJ_ASSERT_RETURN(ioqueue->queue != NULL, PJ_ENOMEM);
+
     PJ_LOG(4, ("pjlib", "epoll I/O Queue created (%p)", ioqueue));
 
@@ -306,5 +320,5 @@
 
     /* os_epoll_ctl. */
-    ev.events = EPOLLIN | EPOLLOUT | EPOLLERR;
+    ev.events = EPOLLIN | EPOLLERR;
     ev.epoll_data = (epoll_data_type)key;
     status = os_epoll_ctl(ioqueue->epfd, EPOLL_CTL_ADD, sock, &ev);
@@ -323,4 +337,6 @@
     ++ioqueue->count;
 
+    //TRACE_((THIS_FILE, "socket registered, count=%d", ioqueue->count));
+
 on_return:
     *p_key = key;
@@ -374,7 +390,14 @@
  */
 static void ioqueue_remove_from_set( pj_ioqueue_t *ioqueue,
-                                     pj_sock_t fd, 
+                                     pj_ioqueue_key_t *key, 
                                      enum ioqueue_event_type event_type)
 {
+    if (event_type == WRITEABLE_EVENT) {
+	struct epoll_event ev;
+
+	ev.events = EPOLLIN | EPOLLERR;
+	ev.epoll_data = (epoll_data_type)key;
+	os_epoll_ctl( ioqueue->epfd, EPOLL_CTL_MOD, key->fd, &ev);
+    }	
 }
 
@@ -386,7 +409,14 @@
  */
 static void ioqueue_add_to_set( pj_ioqueue_t *ioqueue,
-                                pj_sock_t fd,
+                                pj_ioqueue_key_t *key,
                                 enum ioqueue_event_type event_type )
 {
+    if (event_type == WRITEABLE_EVENT) {
+	struct epoll_event ev;
+
+	ev.events = EPOLLIN | EPOLLOUT | EPOLLERR;
+	ev.epoll_data = (epoll_data_type)key;
+	os_epoll_ctl( ioqueue->epfd, EPOLL_CTL_MOD, key->fd, &ev);
+    }	
 }
 
@@ -398,20 +428,29 @@
 {
     int i, count, processed;
-    struct epoll_event events[PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL];
     int msec;
-    struct queue {
-	pj_ioqueue_key_t	*key;
-	enum ioqueue_event_type	 event_type;
-    } queue[PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL];
+    struct epoll_event *events = ioqueue->events;
+    struct queue *queue = ioqueue->queue;
+    pj_timestamp t1, t2;
     
     PJ_CHECK_STACK();
 
     msec = timeout ? PJ_TIME_VAL_MSEC(*timeout) : 9000;
-    
-    count = os_epoll_wait( ioqueue->epfd, events, PJ_ARRAY_SIZE(events), msec);
-    if (count == 0)
+
+    TRACE_((THIS_FILE, "start os_epoll_wait, msec=%d", msec));
+    pj_get_timestamp(&t1);
+ 
+    count = os_epoll_wait( ioqueue->epfd, events, ioqueue->max, msec);
+    if (count == 0) {
+	TRACE_((THIS_FILE, "os_epoll_wait timed out"));
 	return count;
-    else if (count < 0)
+    }
+    else if (count < 0) {
+	TRACE_((THIS_FILE, "os_epoll_wait error"));
 	return -pj_get_netos_error();
+    }
+
+    pj_get_timestamp(&t2);
+    TRACE_((THIS_FILE, "os_epoll_wait returns %d, time=%d usec",
+		       count, pj_elapsed_usec(&t1, &t2)));
 
     /* Lock ioqueue. */
@@ -421,4 +460,6 @@
 	pj_ioqueue_key_t *h = (pj_ioqueue_key_t*)(epoll_data_type)
 				events[i].epoll_data;
+
+	TRACE_((THIS_FILE, "event %d: events=%d", i, events[i].events));
 
 	/*
@@ -487,4 +528,9 @@
 	pj_thread_sleep(msec);
     }
+
+    pj_get_timestamp(&t1);
+    TRACE_((THIS_FILE, "ioqueue_poll() returns %d, time=%d usec",
+		       processed, pj_elapsed_usec(&t2, &t1)));
+
     return processed;
 }
