Request pool cleanup handler

Good day. I’m working on http://github.com/slact/nginx_http_push_module
. and I’ve got this one nasty bug that I’m having a bit of trouble with.

An aside first, though. The way this thing works is by setting up an
rbtree in a shared memory zone. Waiting listener requests are queued up
in channels (represented by nodes on the shared rbtree). Naturally, when
a listener request is finished or aborted, I want it dequeued from a
channel’s “waiting list”. I am doing this with a request pool cleanup
handler, using the following piece of code to set it up:

//test to see if the connection was closed or something.
r->read_event_handler = ngx_http_test_reading; //r is a long-polling
listener request.
//attach a cleaner to remove the request from the channel, if need be
(if the connection goes dead or something)
ngx_http_push_listener_cleanup_t *clndata;
ngx_pool_cleanup_t *cln = ngx_pool_cleanup_add(r->pool,
sizeof(*clndata));
if (cln == NULL) { //make sure we can.
return NGX_ERROR;
}
cln->handler = (ngx_pool_cleanup_pt) ngx_http_push_listener_cleanup;
clndata = (ngx_http_push_listener_cleanup_t *) cln->data;
clndata->channel=channel;
clndata->listener=listener;
ngx_shmtx_lock(&shpool->mutex);
listener->cleanup = clndata;
ngx_shmtx_unlock(&shpool->mutex);

Trouble is, I’m getting (occasional) segfaults from accessing said
ling-polling listener requests that have already been freed. Meaning, I
suspect, the request pool cleanup handler was not called.

Also, I am unable to reproduce this when worker_processes = 1;

Some possibly relevant valgrind output is attached. Coredumps are
getting me nowhere, as said request memory will have already been freed
by the time a segfault occurs.

My questions, then:
Are there any circumstances under which a request pool cleanup handler
will fail to fire? Or am I debugging this in a completely wrong
direction?
Is there a better way to have nginx call a handler upon request
termination?

Thanque,

  • Leo

Hello!

On Sun, Oct 18, 2009 at 07:02:17PM -0400, Leo P. wrote:

set it up:
return NGX_ERROR;
ling-polling listener requests that have already been freed.
Meaning, I suspect, the request pool cleanup handler was not called.

Also, I am unable to reproduce this when worker_processes = 1;

As far as I see, you store pointers to request structure in shared
memory and later use them without checking if you are in the
process they belong to.

This seems to be more or less obvious way to SIGSEGV once you have
more than 1 worker process (which may happen either due to
worker_processes > 1 or configuration reload recently happended).

Maxim D.

D’oh! you’re right. I’ll probably have to do something that calls
ngx_write_channel in some way, from what I understand.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs