You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by am...@apache.org on 2018/04/09 21:08:30 UTC
[trafficserver] branch master updated: Add wrapper class for TSCont
to CPPAPI.
This is an automated email from the ASF dual-hosted git repository.
amc 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 358d38f Add wrapper class for TSCont to CPPAPI.
358d38f is described below
commit 358d38fa576076ee2e124e5f00b037dade466657
Author: Walt Karas <wk...@yahoo-inc.com>
AuthorDate: Thu Mar 15 18:04:21 2018 +0000
Add wrapper class for TSCont to CPPAPI.
---
lib/cppapi/Continuation.cc | 39 ++++++++
lib/cppapi/Makefile.am | 2 +
lib/cppapi/include/atscppapi/Continuation.h | 145 ++++++++++++++++++++++++++++
plugins/test_cppapi/Makefile.inc | 1 +
plugins/test_cppapi/test_cppapi.cc | 135 ++++++++++++++++++++++----
5 files changed, 301 insertions(+), 21 deletions(-)
diff --git a/lib/cppapi/Continuation.cc b/lib/cppapi/Continuation.cc
new file mode 100644
index 0000000..9c3fc8c
--- /dev/null
+++ b/lib/cppapi/Continuation.cc
@@ -0,0 +1,39 @@
+/**
+ 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.
+ */
+
+/**
+ * @file Continuation.cc
+ */
+
+#include <atscppapi/Continuation.h>
+
+namespace atscppapi
+{
+int
+Continuation::_generalEventFunc(TSCont cont, TSEvent event, void *edata)
+{
+ TSReleaseAssert(cont != nullptr);
+
+ Continuation *p = static_cast<Continuation *>(TSContDataGet(cont));
+
+ TSReleaseAssert(p != nullptr);
+
+ return p->_run(event, edata);
+}
+
+} // end namespace atscppapi
diff --git a/lib/cppapi/Makefile.am b/lib/cppapi/Makefile.am
index 87716fc..ba09c95 100644
--- a/lib/cppapi/Makefile.am
+++ b/lib/cppapi/Makefile.am
@@ -25,6 +25,7 @@ libatscppapi_la_SOURCES = \
AsyncTimer.cc \
CaseInsensitiveStringComparator.cc \
ClientRequest.cc \
+ Continuation.cc \
GlobalPlugin.cc \
GzipDeflateTransformation.cc \
GzipInflateTransformation.cc \
@@ -54,6 +55,7 @@ library_include_HEADERS = \
$(base_include_folder)/AsyncTimer.h \
$(base_include_folder)/CaseInsensitiveStringComparator.h \
$(base_include_folder)/ClientRequest.h \
+ $(base_include_folder)/Continuation.h \
$(base_include_folder)/GlobalPlugin.h \
$(base_include_folder)/GzipDeflateTransformation.h \
$(base_include_folder)/GzipInflateTransformation.h \
diff --git a/lib/cppapi/include/atscppapi/Continuation.h b/lib/cppapi/include/atscppapi/Continuation.h
new file mode 100644
index 0000000..dabd1cc
--- /dev/null
+++ b/lib/cppapi/include/atscppapi/Continuation.h
@@ -0,0 +1,145 @@
+/**
+ 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.
+ */
+
+/**
+ * @file Continuation.h
+ * @brief Wrapper class for TS API type TSCont.
+ */
+
+#pragma once
+
+#include <ts/ts.h>
+
+namespace atscppapi
+{
+class Continuation
+{
+public:
+ using Mutex = TSMutex;
+
+ using Action = TSAction;
+
+ // Create continuation, mutexp may be nullptr.
+ //
+ explicit Continuation(Mutex mutexp) : _cont(TSContCreate(_generalEventFunc, mutexp))
+ {
+ TSContDataSet(_cont, static_cast<void *>(this));
+ }
+
+ // Create "empty" continuation, can only be populated by move assignement.
+ //
+ Continuation() : _cont(nullptr) {}
+
+ TSCont
+ asTSCont() const
+ {
+ return _cont;
+ }
+
+ // Get mutex (for "non-empty" continuation).
+ //
+ Mutex
+ mutex()
+ {
+ return _cont ? TSContMutexGet(_cont) : nullptr;
+ }
+
+ void
+ destroy()
+ {
+ if (_cont) {
+ TSContDestroy(_cont);
+ _cont = nullptr;
+ }
+ }
+
+ virtual ~Continuation()
+ {
+ if (_cont) {
+ TSContDestroy(_cont);
+ }
+ }
+
+ // No copying.
+ Continuation(const Continuation &) = delete;
+ Continuation &operator=(const Continuation &) = delete;
+
+ // Moving allowed.
+ Continuation(Continuation &&that)
+ {
+ _cont = that._cont;
+ that._cont = nullptr;
+ TSContDataSet(_cont, static_cast<void *>(this));
+ }
+ Continuation &
+ operator=(Continuation &&that)
+ {
+ if (&that != this) {
+ if (_cont) {
+ TSContDestroy(_cont);
+ }
+ _cont = that._cont;
+ that._cont = nullptr;
+ TSContDataSet(_cont, static_cast<void *>(this));
+ }
+ return *this;
+ }
+
+ explicit operator bool() const { return _cont != nullptr; }
+
+ int
+ call(TSEvent event, void *edata = nullptr)
+ {
+ return TSContCall(_cont, event, edata);
+ }
+
+ // Timeout of zero means no timeout.
+ //
+ Action
+ schedule(TSEvent event, TSHRTime timeout = 0, TSThreadPool tp = TS_THREAD_POOL_DEFAULT)
+ {
+ return TSContSchedule(_cont, timeout, tp);
+ }
+
+ // Timeout of zero means no timeout.
+ //
+ Action
+ httpSchedule(TSEvent event, TSHttpTxn httpTransactionp, TSHRTime timeout = 0)
+ {
+ return TSHttpSchedule(_cont, httpTransactionp, timeout);
+ }
+
+ Action
+ scheduleEvery(TSEvent event, TSHRTime interval /* milliseconds */, TSThreadPool tp = TS_THREAD_POOL_DEFAULT)
+ {
+ return TSContScheduleEvery(_cont, interval, tp);
+ }
+
+protected:
+ // Distinct continuation behavior is acheived by overriding this function in a derived continutation type.
+ //
+ virtual int _run(TSEvent event, void *edata) = 0;
+
+ // This is the event function for all continuations in C++ plugins.
+ //
+ static int _generalEventFunc(TSCont cont, TSEvent event, void *edata);
+
+ TSCont _cont;
+};
+
+} // end namespace atscppapi
diff --git a/plugins/test_cppapi/Makefile.inc b/plugins/test_cppapi/Makefile.inc
index d1a7c97..42a0e7a 100644
--- a/plugins/test_cppapi/Makefile.inc
+++ b/plugins/test_cppapi/Makefile.inc
@@ -15,4 +15,5 @@
# limitations under the License.
pkglib_LTLIBRARIES += test_cppapi/test_cppapi.la
+test_cppapi_test_cppapi_la_LIBADD = $(top_builddir)/lib/cppapi/libatscppapi.la
test_cppapi_test_cppapi_la_SOURCES = test_cppapi/test_cppapi.cc
diff --git a/plugins/test_cppapi/test_cppapi.cc b/plugins/test_cppapi/test_cppapi.cc
index 5de22c9..5a72ffe 100644
--- a/plugins/test_cppapi/test_cppapi.cc
+++ b/plugins/test_cppapi/test_cppapi.cc
@@ -16,19 +16,22 @@
* limitations under the License.
*/
-#include <sstream>
#include <vector>
+#include <utility>
+#include <sstream>
#include <ts/ts.h>
#include <ts/TextView.h>
+#include <atscppapi/Continuation.h>
+
// TSReleaseAssert() doesn't seem to produce any logging output for a debug build, so do both kinds of assert.
//
-#define ASS(EXPR) \
- { \
- TSAssert(EXPR); \
- TSReleaseAssert(EXPR); \
+#define ALWAYS_ASSERT(EXPR) \
+ { \
+ TSAssert(EXPR); \
+ TSReleaseAssert(EXPR); \
}
std::vector<void (*)()> testList;
@@ -41,31 +44,121 @@ struct ATest {
//
#define TEST(TEST_FUNC) ATest t(TEST_FUNC);
-#define TNS_(LN) TestNamespaceName##LN
-
-// Generate a unique name for a separate namespace for each test.
-//
-#define TNS namespace TNS_(__LINE__)
-
// TextView test. This is not testing the actual TextView code, just that it works to call functions in TextView.cc in the core
// from a plugin.
//
-TNS
+namespace TextViewTest
{
- void f()
- {
- ts::TextView tv("abcdefg");
+void
+f()
+{
+ ts::TextView tv("abcdefg");
+
+ std::ostringstream oss;
+
+ oss << tv;
+
+ ALWAYS_ASSERT(ts::memcmp(ts::TextView(oss.str()), tv) == 0)
+}
+
+TEST(f)
+
+} // end namespace TextViewTest
+
+// Test for Continuation class.
+//
+namespace ContinuationTest
+{
+struct {
+ TSEvent event;
+ void *edata;
+} passedToEventFunc;
+
+bool
+checkPassed(TSEvent event, void *edata)
+{
+ return (passedToEventFunc.event == event) and (passedToEventFunc.edata == edata);
+}
+
+class TestCont : public atscppapi::Continuation
+{
+public:
+ TestCont(Mutex m) : atscppapi::Continuation(m) {}
- std::ostringstream oss;
+ TestCont() = default;
- oss << tv;
+private:
+ int
+ _run(TSEvent event, void *edata) override
+ {
+ passedToEventFunc.event = event;
+ passedToEventFunc.edata = edata;
- ASS(ts::memcmp(ts::TextView(oss.str()), tv) == 0)
+ return 666;
}
+};
+
+void
+f()
+{
+ TestCont::Mutex m(TSMutexCreate());
+
+ TestCont c(m);
+
+ ALWAYS_ASSERT(!!c)
+ ALWAYS_ASSERT(c.asTSCont() != nullptr)
+ ALWAYS_ASSERT(c.mutex() == m)
+
+ TestCont c2(std::move(c));
+
+ ALWAYS_ASSERT(!!c2)
+ ALWAYS_ASSERT(c2.asTSCont() != nullptr)
+ ALWAYS_ASSERT(c2.mutex() == m)
+
+ ALWAYS_ASSERT(!c)
+ ALWAYS_ASSERT(c.asTSCont() == nullptr)
+ ALWAYS_ASSERT(c.mutex() == nullptr)
+
+ TestCont c3;
+
+ ALWAYS_ASSERT(!c3)
+ ALWAYS_ASSERT(c3.asTSCont() == nullptr)
+ ALWAYS_ASSERT(c3.mutex() == nullptr)
+
+ c3 = std::move(c2);
+
+ ALWAYS_ASSERT(!!c3)
+ ALWAYS_ASSERT(c3.asTSCont() != nullptr)
+ ALWAYS_ASSERT(c3.mutex() == m)
+
+ ALWAYS_ASSERT(!c2)
+ ALWAYS_ASSERT(c2.asTSCont() == nullptr)
+ ALWAYS_ASSERT(c2.mutex() == nullptr)
+
+ c3.destroy();
+
+ ALWAYS_ASSERT(!c3)
+ ALWAYS_ASSERT(c3.asTSCont() == nullptr)
+ ALWAYS_ASSERT(c3.mutex() == nullptr)
+
+ c = TestCont(m);
+
+ ALWAYS_ASSERT(!!c)
+ ALWAYS_ASSERT(c.asTSCont() != nullptr)
+ ALWAYS_ASSERT(c.mutex() == m)
+
+ ALWAYS_ASSERT(c.call(TS_EVENT_INTERNAL_206) == 666)
+ ALWAYS_ASSERT(checkPassed(TS_EVENT_INTERNAL_206, nullptr))
+
+ int dummy;
+
+ ALWAYS_ASSERT(c.call(TS_EVENT_INTERNAL_207, &dummy) == 666)
+ ALWAYS_ASSERT(checkPassed(TS_EVENT_INTERNAL_207, &dummy))
+}
- TEST(f)
+TEST(f)
-} // end TNS namespace
+} // end namespace ContinuationTest
// Run all the tests.
//
@@ -78,7 +171,7 @@ TSPluginInit(int, const char **)
info.vendor_name = "Apache Software Foundation";
info.support_email = "dev@trafficserver.apache.org";
- ASS(TSPluginRegister(&info) == TS_SUCCESS)
+ ALWAYS_ASSERT(TSPluginRegister(&info) == TS_SUCCESS)
for (auto fp : testList) {
fp();
--
To stop receiving notification emails like this one, please contact
amc@apache.org.