Now that the input and output brigades are only operated on from a
single thread, the extra pool and bucket allocator added as part of
commit cfaef071 can be removed. Also, allocate a single long-lived input
brigade instead of allocating new ones for every socket read.
---
 mod_websocket.c | 49 ++++++++++++++++++-------------------------------
 1 file changed, 18 insertions(+), 31 deletions(-)

diff --git a/mod_websocket.c b/mod_websocket.c
index 8e3bf26..9c62ca5 100644
--- a/mod_websocket.c
+++ b/mod_websocket.c
@@ -465,21 +465,19 @@ static void CALLBACK mod_websocket_plugin_close(const 
WebSocketServer *
 /*
  * Read a buffer of data from the input stream.
  */
-static apr_status_t mod_websocket_read_nonblock(request_rec *r, char *buffer,
+static apr_status_t mod_websocket_read_nonblock(request_rec *r,
+                                                apr_bucket_brigade *bb,
+                                                char *buffer,
                                                 apr_size_t *bufsiz)
 {
-    apr_status_t rv = APR_ENOMEM;
-    apr_bucket_brigade *bb;
+    apr_status_t rv;
 
-    bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
-    if (bb != NULL) {
-        if ((rv =
-             ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
-                            APR_NONBLOCK_READ, *bufsiz)) == APR_SUCCESS) {
-            rv = apr_brigade_flatten(bb, buffer, bufsiz);
-        }
-        apr_brigade_destroy(bb);
+    if ((rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
+                             APR_NONBLOCK_READ, *bufsiz)) == APR_SUCCESS) {
+        rv = apr_brigade_flatten(bb, buffer, bufsiz);
+        apr_brigade_cleanup(bb);
     }
+
     return rv;
 }
 
@@ -893,29 +891,17 @@ static void mod_websocket_data_framing(const 
WebSocketServer *server,
 {
     WebSocketState *state = server->state;
     request_rec *r = state->r;
-    apr_pool_t *pool = NULL;
-    apr_bucket_alloc_t *bucket_alloc;
-    apr_bucket_brigade *obb;
+    apr_bucket_brigade *ibb, *obb;
     apr_pollset_t *pollset;
     apr_pollfd_t pollfd = { 0 };
     const apr_pollfd_t *signalled;
     apr_int32_t pollcnt;
     apr_queue_t * queue;
 
-    /* We cannot use the same bucket allocator for the ouput bucket brigade
-     * obb as the one associated with the connection 
(r->connection->bucket_alloc)
-     * because the same bucket allocator cannot be used in two different
-     * threads, and we use the connection bucket allocator in this
-     * thread - see docs on apr_bucket_alloc_create(). This results in
-     * occasional core dumps. So create our own bucket allocator and pool
-     * for output thread bucket brigade. (Thanks to Alex Bligh -- abligh)
-     */
-
-    if ((apr_pool_create(&pool, r->pool) == APR_SUCCESS) &&
-        ((bucket_alloc = apr_bucket_alloc_create(pool)) != NULL) &&
-        ((obb = apr_brigade_create(pool, bucket_alloc)) != NULL) &&
-        (apr_pollset_create(&pollset, 1, pool, APR_POLLSET_WAKEABLE) == 
APR_SUCCESS) &&
-        (apr_queue_create(&queue, QUEUE_CAPACITY, pool) == APR_SUCCESS)) {
+    if (((ibb = apr_brigade_create(r->pool, r->connection->bucket_alloc)) != 
NULL) &&
+        ((obb = apr_brigade_create(r->pool, r->connection->bucket_alloc)) != 
NULL) &&
+        (apr_pollset_create(&pollset, 1, r->pool, APR_POLLSET_WAKEABLE) == 
APR_SUCCESS) &&
+        (apr_queue_create(&queue, QUEUE_CAPACITY, r->pool) == APR_SUCCESS)) {
         unsigned char block[BLOCK_DATA_SIZE];
         apr_int64_t block_size;
         unsigned char status_code_buffer[2];
@@ -935,7 +921,7 @@ static void mod_websocket_data_framing(const 
WebSocketServer *server,
         state->queue = queue;
 
         /* Initialize the pollset */
-        pollfd.p = pool;
+        pollfd.p = r->pool;
         pollfd.desc_type = APR_POLL_SOCKET;
         pollfd.reqevents = APR_POLLIN;
         pollfd.desc.s = ap_get_conn_socket(state->r->connection);
@@ -960,7 +946,7 @@ static void mod_websocket_data_framing(const 
WebSocketServer *server,
 
             /* Check to see if there is any data to read. */
             block_size = sizeof(block);
-            rv = mod_websocket_read_nonblock(r, (char *)block, &block_size);
+            rv = mod_websocket_read_nonblock(r, ibb, (char *)block, 
&block_size);
 
             if (rv == APR_SUCCESS) {
                 mod_websocket_handle_incoming(server, block, block_size,
@@ -1026,8 +1012,9 @@ static void mod_websocket_data_framing(const 
WebSocketServer *server,
                                     status_code_buffer,
                                     sizeof(status_code_buffer));
 
-        /* We are done with the bucket brigade */
+        /* We are done with the bucket brigades */
         state->obb = NULL;
+        apr_brigade_destroy(ibb);
         apr_brigade_destroy(obb);
 
         state->pollset = NULL;
-- 
2.1.1

Reply via email to