Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/tscpp/api/TransactionPlugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ class TransactionPlugin : public Plugin
*/
std::shared_ptr<Mutex> getMutex();

std::shared_ptr<Mutex> getMutex(TSHttpTxn);

private:
TransactionPluginState *state_; /**< The internal state for a TransactionPlugin */
friend class utils::internal;
Expand Down
6 changes: 6 additions & 0 deletions src/tscpp/api/TransactionPlugin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ TransactionPlugin::getMutex()
return state_->mutex_;
}

std::shared_ptr<Mutex>
TransactionPlugin::getMutex(TSHttpTxn txnp)
{
return state_->ats_txn_handle_ == txnp ? state_->mutex_ : nullptr;
}

bool
TransactionPlugin::isWebsocket() const
{
Expand Down
16 changes: 10 additions & 6 deletions src/tscpp/api/utils_internal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,14 @@ cleanupTransaction(Transaction &transaction, TSHttpTxn ats_txn_handle)
}

void
cleanupTransactionPlugin(Plugin *plugin)
cleanupTransactionPlugin(Plugin *plugin, TSHttpTxn ats_txn_handle)
{
TransactionPlugin *transaction_plugin = static_cast<TransactionPlugin *>(plugin);
std::shared_ptr<Mutex> trans_mutex = utils::internal::getTransactionPluginMutex(*transaction_plugin);
std::shared_ptr<Mutex> trans_mutex = utils::internal::getTransactionPluginMutex(*transaction_plugin, ats_txn_handle);
if (trans_mutex == nullptr) {
LOG_ERROR("TransactionPlugin use-after-free! plugin %p, txn %p", plugin, ats_txn_handle);
return;
}
LOG_DEBUG("Locking TransactionPlugin mutex to delete transaction plugin at %p", transaction_plugin);
trans_mutex->lock();
delete transaction_plugin;
Expand Down Expand Up @@ -96,7 +100,7 @@ handleTransactionEvents(TSCont cont, TSEvent event, void *edata)
resetTransactionHandles(transaction, event);
const std::list<TransactionPlugin *> &plugins = utils::internal::getTransactionPlugins(transaction);
for (auto plugin : plugins) {
cleanupTransactionPlugin(plugin);
cleanupTransactionPlugin(plugin, ats_txn_handle);
}
cleanupTransaction(transaction, ats_txn_handle);
} break;
Expand Down Expand Up @@ -158,7 +162,7 @@ void inline invokePluginForEvent(Plugin *plugin, TSHttpTxn ats_txn_handle, TSEve
case TS_EVENT_HTTP_TXN_CLOSE:
if (plugin) {
plugin->handleTxnClose(transaction);
cleanupTransactionPlugin(plugin);
cleanupTransactionPlugin(plugin, ats_txn_handle);
} else {
LOG_ERROR("stray event TS_EVENT_HTTP_TXN_CLOSE, no transaction plugin to handle it!");
}
Expand All @@ -185,9 +189,9 @@ utils::internal::getTransaction(TSHttpTxn ats_txn_handle)
}

std::shared_ptr<Mutex>
utils::internal::getTransactionPluginMutex(TransactionPlugin &transaction_plugin)
utils::internal::getTransactionPluginMutex(TransactionPlugin &transaction_plugin, TSHttpTxn txnp)
{
return transaction_plugin.getMutex();
return transaction_plugin.getMutex(txnp);
}

TSHttpHookID
Expand Down
2 changes: 1 addition & 1 deletion src/tscpp/api/utils_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ namespace utils
static HttpVersion getHttpVersion(TSMBuffer hdr_buf, TSMLoc hdr_loc);
static void initTransactionManagement();
static std::string consumeFromTSIOBufferReader(TSIOBufferReader);
static std::shared_ptr<Mutex> getTransactionPluginMutex(TransactionPlugin &);
static std::shared_ptr<Mutex> getTransactionPluginMutex(TransactionPlugin &, TSHttpTxn);
static Transaction &getTransaction(TSHttpTxn);

static AsyncHttpFetchState *
Expand Down