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 77fb66b Add generic "guard" class (PostScript) for exception and early function return safety. 77fb66b is described below commit 77fb66b114fd18defc9a0d161992de72c7ef30af Author: Walter Karas <wka...@oath.com> AuthorDate: Thu Jul 12 10:46:53 2018 -0500 Add generic "guard" class (PostScript) for exception and early function return safety. --- lib/ts/Makefile.am | 4 +- lib/ts/PostScript.h | 68 +++++++++++++++++++++++++++++++ lib/ts/unit-tests/test_PostScript.cc | 77 ++++++++++++++++++++++++++++++++++++ 3 files changed, 148 insertions(+), 1 deletion(-) diff --git a/lib/ts/Makefile.am b/lib/ts/Makefile.am index e0bebb8..4b9d0be 100644 --- a/lib/ts/Makefile.am +++ b/lib/ts/Makefile.am @@ -20,7 +20,7 @@ include $(top_srcdir)/build/tidy.mk library_includedir=$(includedir)/ts -library_include_HEADERS = apidefs.h TextView.h +library_include_HEADERS = apidefs.h TextView.h PostScript.h noinst_PROGRAMS = mkdfa CompileParseRules check_PROGRAMS = test_tsutil test_arena test_atomic test_freelist test_geometry test_List test_Map test_Vec test_X509HostnameValidator test_tslib @@ -75,6 +75,7 @@ libtsutil_la_SOURCES = \ EventNotify.h \ fastlz.c \ fastlz.h \ + PostScript.h \ Hash.cc \ HashFNV.cc \ HashFNV.h \ @@ -268,6 +269,7 @@ test_tslib_SOURCES = \ unit-tests/unit_test_main.cc \ unit-tests/test_BufferWriter.cc \ unit-tests/test_BufferWriterFormat.cc \ + unit-tests/test_PostScript.cc \ unit-tests/test_ink_inet.cc \ unit-tests/test_IntrusiveDList.cc \ unit-tests/test_IntrusivePtr.cc \ diff --git a/lib/ts/PostScript.h b/lib/ts/PostScript.h new file mode 100644 index 0000000..af91471 --- /dev/null +++ b/lib/ts/PostScript.h @@ -0,0 +1,68 @@ +/** @file + + Generic "guard" class templates. The destructor calls a function object with arbitrary parameters. This utility is + available in both the core and plugins. + + @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. + */ + +#pragma once + +#include <tuple> + +namespace ts +{ +// The destructor of this class calls the function object passed to its constructor, with the given arguments. +// For example: +// ts::PostScript g(TSHandleMLocRelease, bufp, parent, hdr); +// +// The release() member will prevent the call to the function upon destruction. +// +// Helpful in avoiding errors due to exception throws or error function return points, like the one that caused +// Heartbleed. +// +template <typename Callable, typename... Args> class PostScript +{ +public: + PostScript(Callable f, Args &&... args) : _f(f), _argsTuple(args...) {} + + ~PostScript() + { + if (_armed) { + std::apply(_f, _argsTuple); + } + } + + void + release() + { + _armed = false; + } + + // No copying or moving. + PostScript(const PostScript &) = delete; + PostScript &operator=(const PostScript &) = delete; + +private: + bool _armed = true; + Callable _f; + std::tuple<Args...> _argsTuple; +}; + +} // end namespace ts diff --git a/lib/ts/unit-tests/test_PostScript.cc b/lib/ts/unit-tests/test_PostScript.cc new file mode 100644 index 0000000..1f95fec --- /dev/null +++ b/lib/ts/unit-tests/test_PostScript.cc @@ -0,0 +1,77 @@ +/** @file + + Unit tests for PostScript.h. + + @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 "catch.hpp" +#include <ts/PostScript.h> + +namespace +{ +int f1Called; +int f2Called; +int f3Called; + +void +f1(int a, double b, int c) +{ + ++f1Called; + + REQUIRE(a == 1); + REQUIRE(b == 2.0); + REQUIRE(c == 3); +} + +void +f2(double a) +{ + ++f2Called; +} + +void +f3(int a, double b) +{ + ++f3Called; + + REQUIRE(a == 5); + REQUIRE(b == 6.0); +} + +} // namespace + +TEST_CASE("PostScript", "[PSC]") +{ + int lambdaCalled = 0; + + { + ts::PostScript g1(f1, 1, 2.0, 3); + ts::PostScript g2(f2, 4); + ts::PostScript g3(f3, 5, 6.0); + ts::PostScript g4([&]() -> void { ++lambdaCalled; }); + + g2.release(); + } + + REQUIRE(f1Called == 1); + REQUIRE(f2Called == 0); + REQUIRE(f3Called == 1); + REQUIRE(lambdaCalled == 1); +}