summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordimitri staessens <[email protected]>2017-02-04 20:05:20 +0100
committerdimitri staessens <[email protected]>2017-02-04 20:05:20 +0100
commit9301dcbc95c95a82eba9e831f49253dcad73abb2 (patch)
tree2881368b3fcb28c96c5b9dac6c524d709288f99c
parenta30e244407655d16429ef442ac23db43a548bf95 (diff)
downloadouroboros-9301dcbc95c95a82eba9e831f49253dcad73abb2.tar.gz
ouroboros-9301dcbc95c95a82eba9e831f49253dcad73abb2.zip
lib: Handle receiving CDAP reply before wait
In extreme cases, the response to a CDAP request can arrive before the AE doing the request has called cdap_request_wait. This PR handles it by waiting for the state to move away from INIT before responding.
-rw-r--r--src/lib/cdap_req.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/src/lib/cdap_req.c b/src/lib/cdap_req.c
index 565cafd0..2f55b107 100644
--- a/src/lib/cdap_req.c
+++ b/src/lib/cdap_req.c
@@ -108,6 +108,7 @@ int cdap_req_wait(struct cdap_req * creq)
}
creq->state = REQ_PENDING;
+ pthread_cond_broadcast(&creq->cond);
while (creq->state == REQ_PENDING) {
ret = -pthread_cond_timedwait(&creq->cond,
@@ -131,13 +132,20 @@ int cdap_req_wait(struct cdap_req * creq)
return ret;
}
-void cdap_req_respond(struct cdap_req * creq, int response, buffer_t data)
+void cdap_req_respond(struct cdap_req * creq,
+ int response,
+ buffer_t data)
{
assert(creq);
pthread_mutex_lock(&creq->lock);
+ while (creq->state == REQ_INIT)
+ pthread_cond_wait(&creq->cond, &creq->lock);
+
if (creq->state != REQ_PENDING) {
+ creq->state = REQ_NULL;
+ pthread_cond_broadcast(&creq->cond);
pthread_mutex_unlock(&creq->lock);
return;
}