commit fa70a4804614dc2650cddf657df9c78c6307087d
Author: Jim Meyering <meyering(a)redhat.com>
Date: Fri May 6 11:32:22 2011 +0200
iwhd: don't segfault during garbage collection
The fact that microhttpd starts its own processes that then call our
code and manipulate garbage-collected memory means we have to be
careful to hook each such thread into the GC framework. Commits
8eccf807 and a2eee0a0 did the first part of that, by registering
our two unusual threads with the GC. The problem was that I did
not arrange to unregister them upon thread completion. This change
ensures they call GC_unregister_my_thread to do that job.
* rest.c (prov_list_generator): Call gc_register_thread from the
wrapper, not from the _0 function. Also call GC_unregister_my_thread.
(access_handler): Likewise.
* NEWS (Bug fixes): Mention this.
This should also fix the bug reported here:
http://bugzilla.redhat.com/701482
NEWS | 3 +++
rest.c | 7 ++++---
2 files changed, 7 insertions(+), 3 deletions(-)
---
diff --git a/NEWS b/NEWS
index 1e901a8..a2e8e51 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,9 @@ iwhd NEWS -*- outline
-*-
** Bug fixes
+ iwhd no longer segfaults during garbage-collection
+ [bug introduced in 0.91]
+
iwhd now emits syntactically valid JSON output for the root query.
Before, it omitted the "providers": tag before the list of
provider descriptions. [bug introduced in the beginning]
diff --git a/rest.c b/rest.c
index c3a22ed..d3d8617 100644
--- a/rest.c
+++ b/rest.c
@@ -1701,7 +1701,6 @@ prov_name_compare (const void *av, const void *bv)
static ssize_t
prov_list_generator_0 (void *ctx, uint64_t pos, char *buf, size_t max)
{
- gc_register_thread();
my_state *ms = ctx;
(void)pos;
@@ -1777,7 +1776,9 @@ prov_list_generator_0 (void *ctx, uint64_t pos, char *buf, size_t
max)
static ssize_t
prov_list_generator (void *ctx, uint64_t pos, char *buf, size_t max)
{
+ gc_register_thread();
int ret = prov_list_generator_0 (ctx, pos, buf, max);
+ GC_unregister_my_thread();
return ret;
}
@@ -2190,8 +2191,6 @@ access_handler_0 (void *cctx, struct MHD_Connection *conn, const
char *url,
struct MHD_Response *resp;
my_state *ms = *rctx;
- gc_register_thread();
-
if (ms) {
return ms->handler(cctx,conn,url,method,version,
data,data_size,rctx);
@@ -2245,8 +2244,10 @@ access_handler (void *cctx, struct MHD_Connection *conn, const char
*url,
const char *method, const char *version, const char *data,
size_t *data_size, void **rctx)
{
+ gc_register_thread();
int ret = access_handler_0 (cctx, conn, url, method, version,
data, data_size, rctx);
+ GC_unregister_my_thread();
return ret;
}