diff --git a/asyncprotocol.h b/asyncprotocol.h index 5e79e968..24549ad3 100644 --- a/asyncprotocol.h +++ b/asyncprotocol.h @@ -33,6 +33,7 @@ typedef enum { #define AQU_POP_CMD -5 struct __async_txn { + int ref_counter; /**< reference counter (reference counted object) */ pAsyncUnit unit; /**< unit that transaction is associated with */ int txn_state; /**< protocol handler transaction parse state */ ATX_STATUS txn_status; /**< status of the transaction OK, Error, ... */ diff --git a/asyncqueue.c b/asyncqueue.c index e1a91337..fc075718 100644 --- a/asyncqueue.c +++ b/asyncqueue.c @@ -89,27 +89,36 @@ static const char *state_name(AsyncState the_state) return ""; } +/* + * Free the transaction and buffers + */ +static void free_transaction(pAsyncTxn myTxn) +{ + if (myTxn) { + if (--myTxn->ref_counter > 0) + return; + /* + * Allow kill_private to clean it all if it wants + */ + if (myTxn->kill_private) + myTxn->kill_private(myTxn); + if (myTxn->out_buf) + free(myTxn->out_buf); + if (myTxn->inp_buf) + free(myTxn->inp_buf); + if (myTxn->proto_private) + free(myTxn->proto_private); + free(myTxn); + } +} + /* * Free the command and transaction structures and their contents */ static void free_command(pAQ_Cmd myCmd) { if (myCmd) { - pAsyncTxn myTxn = myCmd->tran; - if (myTxn) { - /* - * Allow kill_private to clean it all if it wants - */ - if (myTxn->kill_private) - myTxn->kill_private(myTxn); - if (myTxn->out_buf) - free(myTxn->out_buf); - if (myTxn->inp_buf) - free(myTxn->inp_buf); - if (myTxn->proto_private) - free(myTxn->proto_private); - free(myTxn); - } + free_transaction(myCmd->tran); free(myCmd); } } @@ -735,9 +744,23 @@ pAsyncTxn AsyncUnitPrepareTxn(pAsyncUnit unit, myTxn->unit = unit; myTxn->handleResponse = callback; myTxn->cntx = context; + myTxn->ref_counter = 1; return myTxn; } +pAsyncTxn AsyncUnitHoldTxn(pAsyncTxn txn) +{ + if (txn) + txn->ref_counter++; + return txn; +} + +void AsyncUnitFreeTxn(pAsyncTxn txn) +{ + if (txn) + free_transaction(txn); +} + int AsyncUnitSendTxn(pAsyncUnit unit, const char *command, int cmd_len, AsyncTxnHandler callback, void *context, int rsp_len) diff --git a/asyncqueue.h b/asyncqueue.h index 669916c3..7ae70579 100644 --- a/asyncqueue.h +++ b/asyncqueue.h @@ -75,6 +75,16 @@ pAsyncTxn AsyncUnitPrepareTxn(pAsyncUnit unit, AsyncTxnHandler responseHandler, void *context, int rsp_len); +/** \brief clone a pointer to the transaction - must use AsyncUnitFreeTxn + * \param txn the transaction to clone + */ +pAsyncTxn AsyncUnitHoldTxn(pAsyncTxn txn); + +/** \brief free a cloned transaction + * \param txn the transaction to free (returned by AsyncUnitHoldTxn) + */ +void AsyncUnitFreeTxn(pAsyncTxn txn); + /** \brief prepare and queue a transaction * * \param unit AsyncUnit