From b869d9aabc1a4e12ad74aa325c3ac9d0591312b3 Mon Sep 17 00:00:00 2001 From: Eygene Ryabinkin Date: Wed, 4 Aug 2010 13:05:08 +0400 Subject: [PATCH] Implement reference counting for requests The problem is that when the request is relayed to the MOM (from modify_job() via relay_to_mom()), the caller of modify_job() (req_modifyjob()) will continue its work and will call reply_ack() on the request, so it will be freed. But relay_to_mom() saves the pointer to the request in the list of work tasks (via issue_Drequest()), so later the function process_Dreply() will operate on the already free()'d pointer. Please, note that we also have req_modifyarray() that will relay modify requests to a multiple MOMs, and every instance of relayer will free the request. So I think that refcounting is the best way to handle such situation. Signed-off-by: Eygene Ryabinkin --- src/include/batch_request.h | 1 + src/server/process_request.c | 8 ++++++++ src/server/req_modify.c | 2 ++ 3 files changed, 11 insertions(+), 0 deletions(-) diff --git a/src/include/batch_request.h b/src/include/batch_request.h index 54c7d90..c6a794b 100644 --- a/src/include/batch_request.h +++ b/src/include/batch_request.h @@ -318,6 +318,7 @@ struct batch_request void *rq_extra; /* optional ptr to extra info */ int rq_noreply; /* Set true if no reply is required */ char *rq_extend; /* request "extension" data */ + unsigned long rq_refcount; /* reference count for this request */ struct batch_reply rq_reply; /* the reply area for this request */ diff --git a/src/server/process_request.c b/src/server/process_request.c index 206eb0a..5127311 100644 --- a/src/server/process_request.c +++ b/src/server/process_request.c @@ -1120,6 +1120,8 @@ struct batch_request *alloc_br( req->rq_time = time_now; req->rq_reply.brp_choice = BATCH_REPLY_CHOICE_NULL; req->rq_noreply = FALSE; /* indicate reply is needed */ + /* XXX: must be lock protected if we will go multithreaded. */ + req->rq_refcount = 1; append_link(&svr_requests, &req->rq_link, req); @@ -1209,6 +1211,12 @@ void free_br( struct batch_request *preq) { + /* XXX: must be lock protected if we will go multithreaded. */ + preq->rq_refcount--; + + if (preq->rq_refcount > 0) + return; + delete_link(&preq->rq_link); reply_free(&preq->rq_reply); diff --git a/src/server/req_modify.c b/src/server/req_modify.c index c79a209..db39cde 100644 --- a/src/server/req_modify.c +++ b/src/server/req_modify.c @@ -443,6 +443,8 @@ int modify_job( return(rc); /* unable to get to MOM */ } + /* XXX: must be lock protected if we will go multithreaded. */ + preq->rq_refcount++; return(0); } -- 1.7.0.6