This is an automated email from the ASF dual-hosted git repository.
shinrich 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 ae094ab Avoid the auto-reschedule with dispatchEvent
ae094ab is described below
commit ae094ab660eb67fc9ec019c086de8a4b07c914f4
Author: Susan Hinrichs <[email protected]>
AuthorDate: Fri Nov 30 16:21:44 2018 +0000
Avoid the auto-reschedule with dispatchEvent
---
.../api/functions/TSContCall.en.rst | 25 +++++--------
iocore/eventsystem/Continuation.cc | 42 ----------------------
iocore/eventsystem/I_Continuation.h | 14 --------
iocore/eventsystem/Makefile.am | 1 -
iocore/net/UnixNetVConnection.cc | 11 ++++--
proxy/http/HttpConfig.cc | 6 +++-
proxy/http/HttpSM.cc | 10 +++---
proxy/http/HttpTunnel.cc | 4 +--
src/traffic_server/InkAPI.cc | 22 ++++++++++--
9 files changed, 50 insertions(+), 85 deletions(-)
diff --git a/doc/developer-guide/api/functions/TSContCall.en.rst
b/doc/developer-guide/api/functions/TSContCall.en.rst
index 9da6a31..5453bb3 100644
--- a/doc/developer-guide/api/functions/TSContCall.en.rst
+++ b/doc/developer-guide/api/functions/TSContCall.en.rst
@@ -44,24 +44,17 @@ As a result :func:`TSContCall` will effectively do::
return CallbackHandler(contp, event, edata);
-:func:`TSContCall` will check :arg:`contp` for a mutex. If there is a mutex an
attempt will be made
-to lock that mutex. If either there is no mutex, or the mutex lock was
acquired, the handler will be
-called directly. Otherwise there is a mutex and it was not successfully
locked. In that case an
-event will be scheduled to dispatch as soon as possible, but not in the
current call stack. The
-nature of event dispatch means the event will not be dispatched until the
mutext can be locked. In
-all cases the handler in :arg:`contp` will be called with the same arguments.
:func:`TSContCall`
-will return 0 if a mutex was present but the lock was not acquired. Otherwise
it will return the
+If there is a mutex associated with :arg:`contp`, :func:`TSComtCall` assumes
that mutex is held already.
+:func:`TSContCall` will directly call the handler associated with the
continuation. It will return the
value returned by the handler in :arg:`contp`.
-If the scheduling behavior of :func:`TSContCall` isn't appropriate, either
:arg:`contp` must not
-have a mutex, or the plugin must acquire the lock on the mutex for
:arg:`contp` before calling
-:func:`TSContCall`. See :func:`TSContMutexGet` and :func:`TSMutexLockTry` for
mechanisms for doing
-the latter. This is what :func:`TSContCall` does internally, and should be
done by the plugin only
-if a different approach for waiting for the lock is needed. The most common
case is the code called
-by :func:`TSContCall` must complete before further code is executed at the
call site. An alternative
-approach to handling the locking directly would be to split the call site in
to two continuations,
-one of which is signalled (possibly via :func:`TSContCall`) from the original
:func:`TSContCall`
-target.
+If :arg:`contp` has a mutex, the plugin must acquire the lock on the mutex for
:arg:`contp` before calling
+:func:`TSContCall`. See :func:`TSContMutexGet` and :func:`TSMutexLockTry` for
mechanisms for doing this.
+
+The most common case is the code called by :func:`TSContCall` must complete
before further code is executed
+at the call site. An alternative approach to handling the locking directly
would be to split the call site
+into two continuations, one of which is signalled (possibly via
:func:`TSContCall`) from the original
+:func:`TSContCall` target.
Note mutexes returned by :func:`TSMutexCreate` are recursive mutexes,
therefore if the lock is
already held on the thread of execution acquiring the lock again is very fast.
Mutexes are also
diff --git a/iocore/eventsystem/Continuation.cc
b/iocore/eventsystem/Continuation.cc
deleted file mode 100644
index c693632..0000000
--- a/iocore/eventsystem/Continuation.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-/** @file
-
- Contination.cc
-
- @section license License
-
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
-#include "I_EventSystem.h"
-#include "I_Continuation.h"
-
-int
-Continuation::dispatchEvent(int event, void *data)
-{
- if (mutex) {
- EThread *t = this_ethread();
- MUTEX_TRY_LOCK(lock, this->mutex, t);
- if (!lock.is_locked()) {
- t->schedule_imm(this, event, data);
- return 0;
- } else {
- return (this->*handler)(event, data);
- }
- } else {
- return (this->*handler)(event, data);
- }
-}
diff --git a/iocore/eventsystem/I_Continuation.h
b/iocore/eventsystem/I_Continuation.h
index bd73f71..140a11d 100644
--- a/iocore/eventsystem/I_Continuation.h
+++ b/iocore/eventsystem/I_Continuation.h
@@ -165,20 +165,6 @@ public:
return (this->*handler)(event, data);
}
- /**
- Receives the event code and data for an Event.
-
- It will attempt to get the lock for the continuation, and reschedule
- the event if the lock cannot be obtained. If the lock can be obtained
- dispatchEvent acts like handleEvent.
-
- @param event Event code to be passed at callback (Processor specific).
- @param data General purpose data related to the event code (Processor
specific).
- @return State machine and processor specific return code.
-
- */
- int dispatchEvent(int event = CONTINUATION_EVENT_NONE, void *data = nullptr);
-
protected:
/**
Constructor of the Continuation object. It should not be used
diff --git a/iocore/eventsystem/Makefile.am b/iocore/eventsystem/Makefile.am
index d481f40..6f44a16 100644
--- a/iocore/eventsystem/Makefile.am
+++ b/iocore/eventsystem/Makefile.am
@@ -59,7 +59,6 @@ libinkevent_a_SOURCES = \
P_UnixSocketManager.h \
P_VConnection.h \
P_VIO.h \
- Continuation.cc \
Processor.cc \
ProtectedQueue.cc \
ProxyAllocator.cc \
diff --git a/iocore/net/UnixNetVConnection.cc b/iocore/net/UnixNetVConnection.cc
index ca5e341..2e9edfc 100644
--- a/iocore/net/UnixNetVConnection.cc
+++ b/iocore/net/UnixNetVConnection.cc
@@ -1087,8 +1087,15 @@ UnixNetVConnection::acceptEvent(int event, Event *e)
if (active_timeout_in) {
UnixNetVConnection::set_active_timeout(active_timeout_in);
}
-
- action_.continuation->dispatchEvent(NET_EVENT_ACCEPT, this);
+ if (action_.continuation->mutex != nullptr) {
+ MUTEX_TRY_LOCK(lock3, action_.continuation->mutex, t);
+ if (!lock3.is_locked()) {
+ ink_release_assert(0);
+ }
+ action_.continuation->handleEvent(NET_EVENT_ACCEPT, this);
+ } else {
+ action_.continuation->handleEvent(NET_EVENT_ACCEPT, this);
+ }
return EVENT_DONE;
}
diff --git a/proxy/http/HttpConfig.cc b/proxy/http/HttpConfig.cc
index 13b1125..887fe5e 100644
--- a/proxy/http/HttpConfig.cc
+++ b/proxy/http/HttpConfig.cc
@@ -1221,7 +1221,11 @@ HttpConfig::startup()
OutboundConnTrack::config_init(&c.outbound_conntrack,
&c.oride.outbound_conntrack);
- http_config_cont->dispatchEvent(EVENT_NONE, nullptr);
+ MUTEX_TRY_LOCK(lock, http_config_cont->mutex, this_ethread());
+ if (!lock.is_locked()) {
+ ink_release_assert(0);
+ }
+ http_config_cont->handleEvent(EVENT_NONE, nullptr);
return;
}
diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc
index 48ccfc6..514e9f9 100644
--- a/proxy/http/HttpSM.cc
+++ b/proxy/http/HttpSM.cc
@@ -555,7 +555,7 @@ HttpSM::setup_client_read_request_header()
ua_entry->read_vio = ua_txn->do_io_read(this, INT64_MAX,
ua_buffer_reader->mbuf);
// The header may already be in the buffer if this
// a request from a keep-alive connection
- dispatchEvent(VC_EVENT_READ_READY, ua_entry->read_vio);
+ handleEvent(VC_EVENT_READ_READY, ua_entry->read_vio);
}
void
@@ -888,7 +888,7 @@ HttpSM::state_watch_for_client_abort(int event, void *data)
"[%" PRId64 "] [watch_for_client_abort] "
"forwarding event %s to tunnel",
sm_id, HttpDebugNames::get_event_name(event));
- tunnel.dispatchEvent(event, c->write_vio);
+ tunnel.handleEvent(event, c->write_vio);
return 0;
} else {
tunnel.kill_tunnel();
@@ -4015,7 +4015,7 @@ HttpSM::do_remap_request(bool run_inline)
if (!ret) {
SMDebug("url_rewrite", "Could not find a valid remapping entry for this
request [%" PRId64 "]", sm_id);
if (!run_inline) {
- dispatchEvent(EVENT_REMAP_COMPLETE, nullptr);
+ handleEvent(EVENT_REMAP_COMPLETE, nullptr);
}
return;
}
@@ -5425,13 +5425,13 @@ HttpSM::handle_server_setup_error(int event, void *data)
ua_producer->alive = false;
ua_producer->handler_state = HTTP_SM_POST_SERVER_FAIL;
- tunnel.dispatchEvent(VC_EVENT_ERROR, c->write_vio);
+ tunnel.handleEvent(VC_EVENT_ERROR, c->write_vio);
return;
}
} else {
// c could be null here as well
if (c != nullptr) {
- tunnel.dispatchEvent(event, c->write_vio);
+ tunnel.handleEvent(event, c->write_vio);
return;
}
}
diff --git a/proxy/http/HttpTunnel.cc b/proxy/http/HttpTunnel.cc
index 86ca78b..84634c3 100644
--- a/proxy/http/HttpTunnel.cc
+++ b/proxy/http/HttpTunnel.cc
@@ -776,7 +776,7 @@ HttpTunnel::tunnel_run(HttpTunnelProducer *p_arg)
// back to say we are done
if (!is_tunnel_alive()) {
active = false;
- sm->dispatchEvent(HTTP_TUNNEL_EVENT_DONE, this);
+ sm->handleEvent(HTTP_TUNNEL_EVENT_DONE, this);
}
}
@@ -1640,7 +1640,7 @@ HttpTunnel::main_handler(int event, void *data)
if (reentrancy_count == 1) {
reentrancy_count = 0;
active = false;
- sm->dispatchEvent(HTTP_TUNNEL_EVENT_DONE, this);
+ sm->handleEvent(HTTP_TUNNEL_EVENT_DONE, this);
return EVENT_DONE;
} else {
call_sm = true;
diff --git a/src/traffic_server/InkAPI.cc b/src/traffic_server/InkAPI.cc
index fc18b72..810435a 100644
--- a/src/traffic_server/InkAPI.cc
+++ b/src/traffic_server/InkAPI.cc
@@ -1295,7 +1295,16 @@ APIHook::invoke(int event, void *edata)
ink_assert(!"not reached");
}
}
- return m_cont->dispatchEvent(event, edata);
+ if (m_cont->mutex != nullptr) {
+ MUTEX_TRY_LOCK(lock, m_cont->mutex, this_ethread());
+ if (!lock.is_locked()) {
+ // If we cannot get the lock, the caller needs to restructure to handle
rescheduling
+ ink_release_assert(0);
+ }
+ return m_cont->handleEvent(event, edata);
+ } else {
+ return m_cont->handleEvent(event, edata);
+ }
}
APIHook *
@@ -4510,7 +4519,16 @@ int
TSContCall(TSCont contp, TSEvent event, void *edata)
{
Continuation *c = (Continuation *)contp;
- return c->dispatchEvent((int)event, edata);
+ if (c->mutex != nullptr) {
+ MUTEX_TRY_LOCK(lock, c->mutex, this_ethread());
+ if (!lock.is_locked()) {
+ // If we cannot get the lock, the caller needs to restructure to handle
rescheduling
+ ink_release_assert(0);
+ }
+ return c->handleEvent((int)event, edata);
+ } else {
+ return c->handleEvent((int)event, edata);
+ }
}
TSMutex