This is an automated email from the ASF dual-hosted git repository.
duke8253 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new 3cea219 Removed add/prepend. Use append only since we don't have
priority implemented yet
3cea219 is described below
commit 3cea21977b0729633b141682f50b297cb5369463
Author: dyrock <[email protected]>
AuthorDate: Thu Jul 26 17:07:16 2018 -0500
Removed add/prepend. Use append only since we don't have priority
implemented yet
---
iocore/cache/test/stub.cc | 16 ++++--
iocore/net/libinknet_stub.cc | 11 +++-
proxy/InkAPIInternal.h | 99 ++++++++++++++++++++++++++--------
proxy/ProxySession.cc | 78 +++++++++++----------------
proxy/ProxySession.h | 15 +++---
proxy/ProxyTransaction.cc | 10 +++-
proxy/ProxyTransaction.h | 3 +-
proxy/Transform.cc | 2 +-
proxy/http/HttpSM.cc | 94 +++++++++++++-------------------
proxy/http/HttpSM.h | 15 ++----
src/traffic_server/InkAPI.cc | 124 +++++++++++++++++++++++++++++++++++--------
11 files changed, 290 insertions(+), 177 deletions(-)
diff --git a/iocore/cache/test/stub.cc b/iocore/cache/test/stub.cc
index 69205a9..2e5adc2 100644
--- a/iocore/cache/test/stub.cc
+++ b/iocore/cache/test/stub.cc
@@ -39,7 +39,7 @@ APIHooks::append(INKContInternal *cont)
}
int
-APIHook::invoke(int, void *)
+APIHook::invoke(int, void *) const
{
ink_assert(false);
return 0;
@@ -53,21 +53,29 @@ APIHook::next() const
}
APIHook *
-APIHooks::get() const
+APIHooks::head() const
{
return nullptr;
}
void
-APIHooks::prepend(INKContInternal *cont)
+APIHooks::clear()
{
}
+HttpHookState::HttpHookState() {}
+
void
-APIHooks::clear()
+HttpHookState::init(TSHttpHookID id, HttpAPIHooks const *global, HttpAPIHooks
const *ssn, HttpAPIHooks const *txn)
{
}
+APIHook const *
+HttpHookState::getNext()
+{
+ return nullptr;
+}
+
void
ConfigUpdateCbTable::invoke(const char * /* name ATS_UNUSED */)
{
diff --git a/iocore/net/libinknet_stub.cc b/iocore/net/libinknet_stub.cc
index 000eb38..11fee25 100644
--- a/iocore/net/libinknet_stub.cc
+++ b/iocore/net/libinknet_stub.cc
@@ -86,7 +86,7 @@ Log::trace_out(sockaddr const *, unsigned short, char const
*, ...)
#include "InkAPIInternal.h"
int
-APIHook::invoke(int, void *)
+APIHook::invoke(int, void *) const
{
ink_assert(false);
return 0;
@@ -100,7 +100,14 @@ APIHook::next() const
}
APIHook *
-APIHooks::get() const
+APIHook::prev() const
+{
+ ink_assert(false);
+ return nullptr;
+}
+
+APIHook *
+APIHooks::head() const
{
ink_assert(false);
return nullptr;
diff --git a/proxy/InkAPIInternal.h b/proxy/InkAPIInternal.h
index 17ba528..25fab38 100644
--- a/proxy/InkAPIInternal.h
+++ b/proxy/InkAPIInternal.h
@@ -31,6 +31,7 @@
#include "ProxyConfig.h"
#include "P_Cache.h"
#include "I_Tasks.h"
+#include "Plugin.h"
#include "ts/InkAPIPrivateIOCore.h"
#include "ts/experimental.h"
@@ -114,8 +115,9 @@ class APIHook
{
public:
INKContInternal *m_cont;
- int invoke(int event, void *edata);
+ int invoke(int event, void *edata) const;
APIHook *next() const;
+ APIHook *prev() const;
LINK(APIHook, m_link);
};
@@ -123,10 +125,12 @@ public:
class APIHooks
{
public:
- void prepend(INKContInternal *cont);
void append(INKContInternal *cont);
- APIHook *get() const;
+ /// Get the first hook.
+ APIHook *head() const;
+ /// Remove all hooks.
void clear();
+ /// Check if there are no hooks.
bool is_empty() const;
private:
@@ -159,8 +163,6 @@ public:
/// Remove all hooks.
void clear();
- /// Add the hook @a cont to the front of the hooks for @a id.
- void prepend(ID id, INKContInternal *cont);
/// Add the hook @a cont to the end of the hooks for @a id.
void append(ID id, INKContInternal *cont);
/// Get the list of hooks for @a id.
@@ -181,8 +183,11 @@ public:
/// @return @c true if any hooks of type @a id are present.
bool has_hooks_for(ID id) const;
+ /// Get a pointer to the set of hooks for a specific hook @id
+ APIHooks const *operator[](ID id) const;
+
private:
- bool hooks_p = false; ///< Flag for (not) empty container.
+ bool m_hooks_p = false; ///< Flag for (not) empty container.
/// The array of hooks lists.
APIHooks m_hooks[N];
};
@@ -198,28 +203,18 @@ template <typename ID, int N>
void
FeatureAPIHooks<ID, N>::clear()
{
- for (int i = 0; i < N; ++i) {
- m_hooks[i].clear();
- }
- hooks_p = false;
-}
-
-template <typename ID, int N>
-void
-FeatureAPIHooks<ID, N>::prepend(ID id, INKContInternal *cont)
-{
- if (likely(is_valid(id))) {
- hooks_p = true;
- m_hooks[id].prepend(cont);
+ for (auto &h : m_hooks) {
+ h.clear();
}
+ m_hooks_p = false;
}
template <typename ID, int N>
void
FeatureAPIHooks<ID, N>::append(ID id, INKContInternal *cont)
{
- if (likely(is_valid(id))) {
- hooks_p = true;
+ if (is_valid(id)) {
+ m_hooks_p = true;
m_hooks[id].append(cont);
}
}
@@ -228,7 +223,12 @@ template <typename ID, int N>
APIHook *
FeatureAPIHooks<ID, N>::get(ID id) const
{
- return likely(is_valid(id)) ? m_hooks[id].get() : nullptr;
+ return likely(is_valid(id)) ? m_hooks[id].head() : nullptr;
+}
+
+template <typename ID, int N> APIHooks const *FeatureAPIHooks<ID,
N>::operator[](ID id) const
+{
+ return likely(is_valid(id)) ? &(m_hooks[id]) : nullptr;
}
template <typename ID, int N>
@@ -244,7 +244,7 @@ template <typename ID, int N>
bool
FeatureAPIHooks<ID, N>::has_hooks() const
{
- return hooks_p;
+ return m_hooks_p;
}
template <typename ID, int N>
@@ -330,6 +330,59 @@ private:
std::unordered_map<std::string, INKContInternal *> cb_table;
};
+class HttpHookState
+{
+public:
+ /// Scope tags for interacting with a live instance.
+ enum ScopeTag { GLOBAL, SSN, TXN };
+
+ /// Default Constructor
+ HttpHookState();
+
+ /// Initialize the hook state to track up to 3 sources of hooks.
+ /// The argument order to this method is used to break priority ties
(callbacks from earlier args are invoked earlier)
+ /// The order in terms of @a ScopeTag is GLOBAL, SESSION, TRANSACTION.
+ void init(TSHttpHookID id, HttpAPIHooks const *global, HttpAPIHooks const
*ssn = nullptr, HttpAPIHooks const *txn = nullptr);
+
+ /// Select a hook for invocation and advance the state to the next valid hook
+ /// @return nullptr if no current hook.
+ APIHook const *getNext();
+
+ /// Get the hook ID
+ TSHttpHookID id() const;
+
+ /// Temporary function to return true. Later will be used to decide if a
plugin is enabled for the hooks
+ bool is_enabled();
+
+protected:
+ /// Track the state of one scope of hooks.
+ struct Scope {
+ APIHook const *_c; ///< Current hook (candidate for invocation).
+ APIHook const *_p; ///< Previous hook (already invoked).
+
+ /// Initialize the scope.
+ void init(HttpAPIHooks const *scope, TSHttpHookID id);
+ /// Clear the scope.
+ void clear();
+ /// Return the current candidate.
+ APIHook const *candidate();
+ /// Advance state to the next hook.
+ void operator++();
+ };
+
+private:
+ TSHttpHookID _id;
+ Scope _global; ///< Chain from global hooks.
+ Scope _ssn; ///< Chain from session hooks.
+ Scope _txn; ///< Chain from transaction hooks.
+};
+
+inline TSHttpHookID
+HttpHookState::id() const
+{
+ return _id;
+}
+
void api_init();
extern HttpAPIHooks *http_global_hooks;
diff --git a/proxy/ProxySession.cc b/proxy/ProxySession.cc
index 8ca3cfc..7063b9f 100644
--- a/proxy/ProxySession.cc
+++ b/proxy/ProxySession.cc
@@ -77,12 +77,6 @@ static const TSEvent eventmap[TS_HTTP_LAST_HOOK + 1] = {
TS_EVENT_NONE, // TS_HTTP_LAST_HOOK
};
-static bool
-is_valid_hook(TSHttpHookID hookid)
-{
- return (hookid >= 0) && (hookid < TS_HTTP_LAST_HOOK);
-}
-
void
ProxySession::free()
{
@@ -107,34 +101,28 @@ ProxySession::state_api_callout(int event, void *data)
case EVENT_NONE:
case EVENT_INTERVAL:
case TS_EVENT_HTTP_CONTINUE:
- if (likely(is_valid_hook(this->api_hookid))) {
- if (this->api_current == nullptr && this->api_scope ==
API_HOOK_SCOPE_GLOBAL) {
- this->api_current = http_global_hooks->get(this->api_hookid);
- this->api_scope = API_HOOK_SCOPE_LOCAL;
- }
+ if (nullptr == cur_hook) {
+ /// Get the next hook to invoke from HttpHookState
+ cur_hook = hook_state.getNext();
+ }
+ if (nullptr != cur_hook) {
+ APIHook const *hook = cur_hook;
- if (this->api_current == nullptr && this->api_scope ==
API_HOOK_SCOPE_LOCAL) {
- this->api_current = ssn_hook_get(this->api_hookid);
- this->api_scope = API_HOOK_SCOPE_NONE;
- }
+ MUTEX_TRY_LOCK(lock, hook->m_cont->mutex, mutex->thread_holding);
- if (this->api_current) {
- APIHook *hook = this->api_current;
-
- MUTEX_TRY_LOCK(lock, hook->m_cont->mutex, mutex->thread_holding);
- // Have a mutex but did't get the lock, reschedule
- if (!lock.is_locked()) {
- SET_HANDLER(&ProxySession::state_api_callout);
- if (!schedule_event) { // Don't bother to schedule is there is
already one out.
- schedule_event = mutex->thread_holding->schedule_in(this,
HRTIME_MSECONDS(10));
- }
- return 0;
+ // Have a mutex but didn't get the lock, reschedule
+ if (!lock.is_locked()) {
+ SET_HANDLER(&ProxySession::state_api_callout);
+ if (!schedule_event) { // Don't bother if there is already one
+ schedule_event = mutex->thread_holding->schedule_in(this,
HRTIME_MSECONDS(10));
}
-
- this->api_current = this->api_current->next();
- hook->invoke(eventmap[this->api_hookid], this);
return 0;
}
+
+ cur_hook = nullptr; // mark current callback at dispatched.
+ hook->invoke(eventmap[hook_state.id()], this);
+
+ return 0;
}
handle_api_return(event);
@@ -156,12 +144,10 @@ void
ProxySession::do_api_callout(TSHttpHookID id)
{
ink_assert(id == TS_HTTP_SSN_START_HOOK || id == TS_HTTP_SSN_CLOSE_HOOK);
-
- this->api_hookid = id;
- this->api_scope = API_HOOK_SCOPE_GLOBAL;
- this->api_current = nullptr;
-
- if (this->has_hooks()) {
+ hook_state.init(id, http_global_hooks, &api_hooks);
+ /// Verify if there is any hook to invoke
+ cur_hook = hook_state.getNext();
+ if (nullptr != cur_hook) {
SET_HANDLER(&ProxySession::state_api_callout);
this->state_api_callout(EVENT_NONE, nullptr);
} else {
@@ -172,13 +158,11 @@ ProxySession::do_api_callout(TSHttpHookID id)
void
ProxySession::handle_api_return(int event)
{
- TSHttpHookID hookid = this->api_hookid;
+ TSHttpHookID hookid = hook_state.id();
SET_HANDLER(&ProxySession::state_api_callout);
- this->api_hookid = TS_HTTP_LAST_HOOK;
- this->api_scope = API_HOOK_SCOPE_NONE;
- this->api_current = nullptr;
+ cur_hook = nullptr;
switch (hookid) {
case TS_HTTP_SSN_START_HOOK:
@@ -301,7 +285,7 @@ ProxySession::get_server_session() const
TSHttpHookID
ProxySession::get_hookid() const
{
- return api_hookid;
+ return hook_state.id();
}
void
@@ -353,21 +337,21 @@ ProxySession::get_local_addr()
}
void
-ProxySession::ssn_hook_append(TSHttpHookID id, INKContInternal *cont)
+ProxySession::hook_add(TSHttpHookID id, INKContInternal *cont)
{
this->api_hooks.append(id, cont);
}
-void
-ProxySession::ssn_hook_prepend(TSHttpHookID id, INKContInternal *cont)
+APIHook *
+ProxySession::hook_get(TSHttpHookID id) const
{
- this->api_hooks.prepend(id, cont);
+ return this->api_hooks.get(id);
}
-APIHook *
-ProxySession::ssn_hook_get(TSHttpHookID id) const
+HttpAPIHooks const *
+ProxySession::feature_hooks() const
{
- return this->api_hooks.get(id);
+ return &api_hooks;
}
bool
diff --git a/proxy/ProxySession.h b/proxy/ProxySession.h
index b0b3b56..5f40af7 100644
--- a/proxy/ProxySession.h
+++ b/proxy/ProxySession.h
@@ -101,9 +101,7 @@ public:
virtual const char *get_protocol_string() const = 0;
virtual bool is_transparent_passthrough_allowed() const;
- virtual void ssn_hook_append(TSHttpHookID id, INKContInternal *cont);
-
- virtual void ssn_hook_prepend(TSHttpHookID id, INKContInternal *cont);
+ virtual void hook_add(TSHttpHookID id, INKContInternal *cont);
virtual bool is_chunked_encoding_supported() const;
@@ -146,8 +144,8 @@ public:
TSHttpHookID get_hookid() const;
bool has_hooks() const;
- APIHook *ssn_hook_get(TSHttpHookID id) const;
-
+ APIHook *hook_get(TSHttpHookID id) const;
+ HttpAPIHooks const *feature_hooks() const;
////////////////////
// Members
@@ -163,6 +161,9 @@ public:
ink_hrtime ssn_last_txn_time = 0;
protected:
+ // Hook dispatching state
+ HttpHookState hook_state;
+
// XXX Consider using a bitwise flags variable for the following flags, so
// that we can make the best use of internal alignment padding.
@@ -177,9 +178,7 @@ private:
void handle_api_return(int event);
int state_api_callout(int event, void *edata);
- APIHookScope api_scope = API_HOOK_SCOPE_NONE;
- TSHttpHookID api_hookid = TS_HTTP_READ_REQUEST_HDR_HOOK;
- APIHook *api_current = nullptr;
+ APIHook const *cur_hook = nullptr;
HttpAPIHooks api_hooks;
void *user_args[TS_HTTP_MAX_USER_ARG];
diff --git a/proxy/ProxyTransaction.cc b/proxy/ProxyTransaction.cc
index 1ece708..67b9c84 100644
--- a/proxy/ProxyTransaction.cc
+++ b/proxy/ProxyTransaction.cc
@@ -160,9 +160,15 @@ ProxyTransaction::debug() const
}
APIHook *
-ProxyTransaction::ssn_hook_get(TSHttpHookID id) const
+ProxyTransaction::hook_get(TSHttpHookID id) const
{
- return proxy_ssn ? proxy_ssn->ssn_hook_get(id) : nullptr;
+ return proxy_ssn ? proxy_ssn->hook_get(id) : nullptr;
+}
+
+HttpAPIHooks const *
+ProxyTransaction::feature_hooks() const
+{
+ return proxy_ssn ? proxy_ssn->feature_hooks() : nullptr;
}
bool
diff --git a/proxy/ProxyTransaction.h b/proxy/ProxyTransaction.h
index 68c484b..7b16646 100644
--- a/proxy/ProxyTransaction.h
+++ b/proxy/ProxyTransaction.h
@@ -89,7 +89,8 @@ public:
bool debug() const;
- APIHook *ssn_hook_get(TSHttpHookID id) const;
+ APIHook *hook_get(TSHttpHookID id) const;
+ HttpAPIHooks const *feature_hooks() const;
bool has_hooks() const;
HostResStyle get_host_res_style() const;
diff --git a/proxy/Transform.cc b/proxy/Transform.cc
index 3049305..ee1c0af 100644
--- a/proxy/Transform.cc
+++ b/proxy/Transform.cc
@@ -545,7 +545,7 @@ TransformControl::handle_event(int event, void * /* edata
ATS_UNUSED */)
if (http_global_hooks &&
http_global_hooks->get(TS_HTTP_RESPONSE_TRANSFORM_HOOK)) {
m_tvc = transformProcessor.open(this,
http_global_hooks->get(TS_HTTP_RESPONSE_TRANSFORM_HOOK));
} else {
- m_tvc = transformProcessor.open(this, m_hooks.get());
+ m_tvc = transformProcessor.open(this, m_hooks.head());
}
ink_assert(m_tvc != nullptr);
diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc
index 10b82e6..a2117d4 100644
--- a/proxy/http/HttpSM.cc
+++ b/proxy/http/HttpSM.cc
@@ -1401,67 +1401,46 @@ plugins required to work with sni_routing.
}
// FALLTHROUGH
case HTTP_API_CONTINUE:
- if ((cur_hook_id >= 0) && (cur_hook_id < TS_HTTP_LAST_HOOK)) {
- if (!cur_hook) {
- if (cur_hooks == 0) {
- cur_hook = http_global_hooks->get(cur_hook_id);
- cur_hooks++;
- }
- }
- // even if ua_txn is NULL, cur_hooks must
- // be incremented otherwise cur_hooks is not set to 2 and
- // transaction hooks (stored in api_hooks object) are not called.
- if (!cur_hook) {
- if (cur_hooks == 1) {
- if (ua_txn) {
- cur_hook = ua_txn->ssn_hook_get(cur_hook_id);
- }
- cur_hooks++;
- }
+ if (nullptr == cur_hook) {
+ cur_hook = hook_state.getNext();
+ }
+ if (cur_hook) {
+ if (callout_state == HTTP_API_NO_CALLOUT) {
+ callout_state = HTTP_API_IN_CALLOUT;
}
- if (!cur_hook) {
- if (cur_hooks == 2) {
- cur_hook = api_hooks.get(cur_hook_id);
- cur_hooks++;
- }
+
+ MUTEX_TRY_LOCK(lock, cur_hook->m_cont->mutex, mutex->thread_holding);
+
+ // Have a mutex but didn't get the lock, reschedule
+ if (!lock.is_locked()) {
+ api_timer = -Thread::get_hrtime_updated();
+ HTTP_SM_SET_DEFAULT_HANDLER(&HttpSM::state_api_callout);
+ ink_assert(pending_action == nullptr);
+ pending_action = mutex->thread_holding->schedule_in(this,
HRTIME_MSECONDS(10));
+ return 0;
}
- if (cur_hook) {
- if (callout_state == HTTP_API_NO_CALLOUT) {
- callout_state = HTTP_API_IN_CALLOUT;
- }
- MUTEX_TRY_LOCK(lock, cur_hook->m_cont->mutex, mutex->thread_holding);
- // Have a mutex but didn't get the lock, reschedule
- if (!lock.is_locked()) {
- api_timer = -Thread::get_hrtime_updated();
- HTTP_SM_SET_DEFAULT_HANDLER(&HttpSM::state_api_callout);
- ink_assert(pending_action == nullptr);
- pending_action = mutex->thread_holding->schedule_in(this,
HRTIME_MSECONDS(10));
- // Should @a callout_state be reset back to HTTP_API_NO_CALLOUT
here? Because the default
- // handler has been changed the value isn't important to the rest of
the state machine
- // but not resetting means there is no way to reliably detect
re-entrance to this state with an
- // outstanding callout.
- return 0;
- }
- SMDebug("http", "[%" PRId64 "] calling plugin on hook %s at hook %p",
sm_id, HttpDebugNames::get_api_hook_name(cur_hook_id),
- cur_hook);
+ SMDebug("http", "[%" PRId64 "] calling plugin on hook %s at hook %p",
sm_id, HttpDebugNames::get_api_hook_name(cur_hook_id),
+ cur_hook);
- APIHook *hook = cur_hook;
- cur_hook = cur_hook->next();
+ APIHook const *hook = cur_hook;
+ // Need to delay the next hook update until after this hook is called to
handle dynamic
+ // callback manipulation. cur_hook isn't needed to track state (in
hook_state).
+ cur_hook = nullptr;
- if (!api_timer) {
- api_timer = Thread::get_hrtime_updated();
- }
- hook->invoke(TS_EVENT_HTTP_READ_REQUEST_HDR + cur_hook_id, this);
- if (api_timer > 0) { // true if the hook did not call TxnReenable()
- milestone_update_api_time(milestones, api_timer);
- api_timer = -Thread::get_hrtime_updated(); // set in order to track
non-active callout duration
- // which means that if we get back from the invoke with api_timer <
0 we're already
- // tracking a non-complete callout from a chain so just let it ride.
It will get cleaned
- // up in state_api_callback when the plugin re-enables this
transaction.
- }
- return 0;
+ if (!api_timer) {
+ api_timer = Thread::get_hrtime();
+ }
+
+ hook->invoke(TS_EVENT_HTTP_READ_REQUEST_HDR + cur_hook_id, this);
+ if (api_timer > 0) { // true if the hook did not call TxnReenable()
+ milestone_update_api_time(milestones, api_timer);
+ api_timer = -Thread::get_hrtime(); // set in order to track non-active
callout duration
+ // which means that if we get back from the invoke with api_timer < 0
we're already
+ // tracking a non-complete callout from a chain so just let it ride.
It will get cleaned
+ // up in state_api_callback when the plugin re-enables this
transaction.
}
+ return 0;
}
// Map the callout state into api_next
switch (callout_state) {
@@ -5110,6 +5089,7 @@ HttpSM::do_api_callout_internal()
ink_assert(!"not reached");
}
+ hook_state.init(cur_hook_id, http_global_hooks, ua_txn ?
ua_txn->feature_hooks() : nullptr, &api_hooks);
cur_hook = nullptr;
cur_hooks = 0;
state_api_callout(0, nullptr);
@@ -5121,7 +5101,7 @@ HttpSM::do_post_transform_open()
ink_assert(post_transform_info.vc == nullptr);
if (is_action_tag_set("http_post_nullt")) {
- txn_hook_prepend(TS_HTTP_REQUEST_TRANSFORM_HOOK,
transformProcessor.null_transform(mutex.get()));
+ txn_hook_add(TS_HTTP_REQUEST_TRANSFORM_HOOK,
transformProcessor.null_transform(mutex.get()));
}
post_transform_info.vc = transformProcessor.open(this,
api_hooks.get(TS_HTTP_REQUEST_TRANSFORM_HOOK));
@@ -5142,7 +5122,7 @@ HttpSM::do_transform_open()
APIHook *hooks;
if (is_action_tag_set("http_nullt")) {
- txn_hook_prepend(TS_HTTP_RESPONSE_TRANSFORM_HOOK,
transformProcessor.null_transform(mutex.get()));
+ txn_hook_add(TS_HTTP_RESPONSE_TRANSFORM_HOOK,
transformProcessor.null_transform(mutex.get()));
}
hooks = api_hooks.get(TS_HTTP_RESPONSE_TRANSFORM_HOOK);
diff --git a/proxy/http/HttpSM.h b/proxy/http/HttpSM.h
index be81331..ab26c66 100644
--- a/proxy/http/HttpSM.h
+++ b/proxy/http/HttpSM.h
@@ -291,8 +291,7 @@ public:
void dump_state_hdr(HTTPHdr *h, const char *s);
// Functions for manipulating api hooks
- void txn_hook_append(TSHttpHookID id, INKContInternal *cont);
- void txn_hook_prepend(TSHttpHookID id, INKContInternal *cont);
+ void txn_hook_add(TSHttpHookID id, INKContInternal *cont);
APIHook *txn_hook_get(TSHttpHookID id);
bool is_private();
@@ -562,7 +561,8 @@ public:
protected:
TSHttpHookID cur_hook_id = TS_HTTP_LAST_HOOK;
- APIHook *cur_hook = nullptr;
+ APIHook const *cur_hook = nullptr;
+ HttpHookState hook_state;
//
// Continuation time keeper
@@ -677,19 +677,12 @@ HttpSM::find_server_buffer_size()
}
inline void
-HttpSM::txn_hook_append(TSHttpHookID id, INKContInternal *cont)
+HttpSM::txn_hook_add(TSHttpHookID id, INKContInternal *cont)
{
api_hooks.append(id, cont);
hooks_set = true;
}
-inline void
-HttpSM::txn_hook_prepend(TSHttpHookID id, INKContInternal *cont)
-{
- api_hooks.prepend(id, cont);
- hooks_set = true;
-}
-
inline APIHook *
HttpSM::txn_hook_get(TSHttpHookID id)
{
diff --git a/src/traffic_server/InkAPI.cc b/src/traffic_server/InkAPI.cc
index 6d49303..edb4c31 100644
--- a/src/traffic_server/InkAPI.cc
+++ b/src/traffic_server/InkAPI.cc
@@ -1310,12 +1310,23 @@ INKVConnInternal::set_data(int id, void *data)
////////////////////////////////////////////////////////////////////
//
-// APIHook, APIHooks, HttpAPIHooks
+// APIHook, APIHooks, HttpAPIHooks, HttpHookState
//
////////////////////////////////////////////////////////////////////
+APIHook *
+APIHook::next() const
+{
+ return m_link.next;
+}
+
+APIHook *
+APIHook::prev() const
+{
+ return m_link.prev;
+}
int
-APIHook::invoke(int event, void *edata)
+APIHook::invoke(int event, void *edata) const
{
if ((event == EVENT_IMMEDIATE) || (event == EVENT_INTERVAL) || event ==
TS_EVENT_HTTP_TXN_CLOSE) {
if (ink_atomic_increment((int *)&m_cont->m_event_count, 1) < 0) {
@@ -1331,46 +1342,117 @@ APIHook::invoke(int event, void *edata)
}
APIHook *
-APIHook::next() const
+APIHooks::head() const
{
- return m_link.next;
+ return m_hooks.head;
}
void
-APIHooks::prepend(INKContInternal *cont)
+APIHooks::append(INKContInternal *cont)
{
APIHook *api_hook;
api_hook = apiHookAllocator.alloc();
api_hook->m_cont = cont;
- m_hooks.push(api_hook);
+ m_hooks.enqueue(api_hook);
}
void
-APIHooks::append(INKContInternal *cont)
+APIHooks::clear()
{
- APIHook *api_hook;
+ APIHook *hook;
+ while (nullptr != (hook = m_hooks.pop())) {
+ apiHookAllocator.free(hook);
+ }
+}
- api_hook = apiHookAllocator.alloc();
- api_hook->m_cont = cont;
+HttpHookState::HttpHookState() : _id(TS_HTTP_LAST_HOOK) {}
- m_hooks.enqueue(api_hook);
+void
+HttpHookState::init(TSHttpHookID id, HttpAPIHooks const *global, HttpAPIHooks
const *ssn, HttpAPIHooks const *txn)
+{
+ _id = id;
+
+ if (global) {
+ _global.init(global, id);
+ } else {
+ _global.clear();
+ }
+
+ if (ssn) {
+ _ssn.init(ssn, id);
+ } else {
+ _ssn.clear();
+ }
+
+ if (txn) {
+ _txn.init(txn, id);
+ } else {
+ _txn.clear();
+ }
}
-APIHook *
-APIHooks::get() const
+APIHook const *
+HttpHookState::getNext()
{
- return m_hooks.head;
+ APIHook const *zret = nullptr;
+ do {
+ APIHook const *hg = _global.candidate();
+ APIHook const *hssn = _ssn.candidate();
+ APIHook const *htxn = _txn.candidate();
+ zret = nullptr;
+
+ Debug("plugin", "computing next callback for hook %d", _id);
+
+ if (hg) {
+ zret = hg;
+ ++_global;
+ } else if (hssn) {
+ zret = hssn;
+ ++_ssn;
+ } else if (htxn) {
+ zret = htxn;
+ ++_txn;
+ }
+ } while (zret != nullptr && !this->is_enabled());
+
+ return zret;
+}
+
+bool
+HttpHookState::is_enabled()
+{
+ return true;
}
void
-APIHooks::clear()
+HttpHookState::Scope::init(HttpAPIHooks const *feature_hooks, TSHttpHookID id)
{
- APIHook *hook;
- while (nullptr != (hook = m_hooks.pop())) {
- apiHookAllocator.free(hook);
- }
+ APIHooks const *hooks = (*feature_hooks)[id];
+
+ _p = nullptr;
+ _c = hooks->head();
+}
+
+APIHook const *
+HttpHookState::Scope::candidate()
+{
+ /// Simply returns _c hook for now. Later will do priority checking here
+ return _c;
+}
+
+void
+HttpHookState::Scope::operator++()
+{
+ _p = _c;
+ _c = _c->next();
+}
+
+void
+HttpHookState::Scope::clear()
+{
+ _p = _c = nullptr;
}
////////////////////////////////////////////////////////////////////
@@ -4760,7 +4842,7 @@ TSHttpSsnHookAdd(TSHttpSsn ssnp, TSHttpHookID id, TSCont
contp)
sdk_assert(sdk_sanity_check_hook_id(id) == TS_SUCCESS);
ProxySession *cs = reinterpret_cast<ProxySession *>(ssnp);
- cs->ssn_hook_append(id, (INKContInternal *)contp);
+ cs->hook_add(id, (INKContInternal *)contp);
}
int
@@ -4848,7 +4930,7 @@ TSHttpTxnHookAdd(TSHttpTxn txnp, TSHttpHookID id, TSCont
contp)
}
hook = hook->m_link.next;
}
- sm->txn_hook_append(id, (INKContInternal *)contp);
+ sm->txn_hook_add(id, (INKContInternal *)contp);
}
// Private api function for gzip plugin.