Commit 3b4db076 authored by Francis Dupont's avatar Francis Dupont

[5389] Addressed warnings, moved to boost coroutines

parent 7feedc09
......@@ -7,12 +7,6 @@ text is also included below.
-----------------------------------------------------------------------------
The ext/coroutine code is externally maintained and distributed under
the Boost Software License, Version 1.0. (See its accompanying file
ext/coroutine/LICENSE_1_0.txt.)
-----------------------------------------------------------------------------
The Cassandra backend code is distributed under the Apache License, Version 2.0.
The text is available at http://www.apache.org/licenses/LICENSE-2.0. Full
text is also included below in this file.
......
......@@ -77,7 +77,6 @@ report-cpp-coverage:
if HAVE_BOTAN
botan/\* \
endif
ext/coroutine/\* \
gtest/\* \
include/\* \
log4cplus/\* \
......@@ -120,9 +119,6 @@ install-exec-hook:
EXTRA_DIST = tools/path_replacer.sh
EXTRA_DIST += tools/mk_cfgrpt.sh
#### include external sources in the distributed tarball:
EXTRA_DIST += ext/coroutine/coroutine.h
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = dns++.pc
......
......@@ -1000,9 +1000,6 @@ fi
#
# ASIO: we extensively use it as the C++ event management module.
#
# Use our 'coroutine' header from ext
CPPFLAGS="$CPPFLAGS -I\$(top_srcdir)/ext/coroutine"
#
# Doesn't seem to be required?
CPPFLAGS="$CPPFLAGS -DBOOST_ASIO_HEADER_ONLY"
#
......@@ -1190,7 +1187,6 @@ AC_CONFIG_FILES([Makefile
doc/guide/Makefile
doc/version.ent
ext/Makefile
ext/coroutine/Makefile
ext/gtest/Makefile
m4macros/Makefile
src/Makefile
......
SUBDIRS = coroutine
SUBDIRS = .
if HAVE_GTEST_SOURCE
SUBDIRS += gtest
......
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
EXTRA_DIST = LICENSE_1_0.txt
//
// coroutine.h
// ~~~~~~~~~~~
//
// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef COROUTINE_HPP
#define COROUTINE_HPP
// \brief Coroutine object
//
// A coroutine object maintains the state of a re-enterable routine. It
// is assignable and copy-constructible, and can be used as a base class
// for a class that uses it, or as a data member. The copy overhead is
// a single int.
//
// A reentrant function contains a CORO_REENTER (coroutine) { ... }
// block. Whenever an asynchronous operation is initiated within the
// routine, the function is provided as the handler object. (The simplest
// way to do this is to have the reentrant function be the operator()
// member for the coroutine object itself.) For example:
//
// CORO_YIELD socket->async_read_some(buffer, *this);
//
// The CORO_YIELD keyword updates the current status of the coroutine to
// indicate the line number currently being executed. The
// async_read_some() call is initiated, with a copy of the updated
// coroutine as its handler object, and the current coroutine exits. When
// the async_read_some() call finishes, the copied coroutine will be
// called, and will resume processing exactly where the original one left
// off--right after asynchronous call. This allows asynchronous I/O
// routines to be written with a logical flow, step following step, rather
// than as a linked chain of separate handler functions.
//
// When necessary, a coroutine can fork itself using the CORO_FORK keyword.
// This updates the status of the coroutine and makes a copy. The copy can
// then be called directly or posted to the ASIO service queue so that both
// coroutines will continue forward, one "parent" and one "child". The
// is_parent() and is_child() methods indicate which is which.
//
// The CORO_REENTER, CORO_YIELD and CORO_FORK keywords are implemented
// via preprocessor macros. The CORO_REENTER block is actually a large,
// complex switch statement. Because of this, inline variable declaration
// is impossible within CORO_REENTER unless it is done in a subsidiary
// scope--and if it is, that scope cannot contain CORO_YIELD or CORO_FORK
// keywords.
//
// Because coroutines are frequently copied, it is best to minimize copy
// overhead by limiting the size of data members in derived classes.
//
// It should be noted that when a coroutine falls out of scope its memory
// is reclaimed, even though it may be scheduled to resume when an
// asynchronous operation completes. Any shared_ptr<> objects declared in
// the coroutine may be destroyed if their reference count drops to zero,
// in which case the coroutine will have serious problems once it resumes.
// One solution so this is to have the space that will be used by a
// coroutine pre-allocated and stored on a free list; a new coroutine can
// fetch the block of space off a free list, place a shared pointer to it
// on an "in use" list, and carry on. The reference in the "in use" list
// would prevent the data from being destroyed.
class coroutine
{
public:
coroutine() : value_(0) {}
virtual ~coroutine() {}
bool is_child() const { return value_ < 0; }
bool is_parent() const { return !is_child(); }
bool is_complete() const { return value_ == -1; }
int get_value() const { return value_; }
private:
friend class coroutine_ref;
int value_;
};
class coroutine_ref
{
public:
coroutine_ref(coroutine& c) : value_(c.value_), modified_(false) {}
coroutine_ref(coroutine* c) : value_(c->value_), modified_(false) {}
~coroutine_ref() { if (!modified_) value_ = -1; }
operator int() const { return value_; }
int& operator=(int v) { modified_ = true; return value_ = v; }
private:
void operator=(const coroutine_ref&);
int& value_;
bool modified_;
};
#define CORO_REENTER(c) \
switch (coroutine_ref _coro_value = c) \
case -1: if (_coro_value) \
{ \
goto terminate_coroutine; \
terminate_coroutine: \
_coro_value = -1; \
goto bail_out_of_coroutine; \
bail_out_of_coroutine: \
break; \
} \
else case 0:
#define CORO_YIELD \
for (_coro_value = __LINE__;;) \
if (_coro_value == 0) \
{ \
case __LINE__: ; \
break; \
} \
else \
switch (_coro_value ? 0 : 1) \
for (;;) \
case -1: if (_coro_value) \
goto terminate_coroutine; \
else for (;;) \
case 1: if (_coro_value) \
goto bail_out_of_coroutine; \
else case 0:
#define CORO_FORK \
for (_coro_value = -__LINE__;; _coro_value = __LINE__) \
if (_coro_value == __LINE__) \
{ \
case -__LINE__: ; \
break; \
} \
else
#endif // COROUTINE_HPP
......@@ -74,7 +74,7 @@ if test "${boost_include_path}" ; then
BOOST_INCLUDES="-I${boost_include_path}"
CPPFLAGS="$CPPFLAGS $BOOST_INCLUDES"
fi
AC_CHECK_HEADERS([boost/shared_ptr.hpp boost/foreach.hpp boost/interprocess/sync/interprocess_upgradable_mutex.hpp boost/date_time/posix_time/posix_time_types.hpp boost/bind.hpp boost/function.hpp boost/asio.hpp boost/asio/ip/address.hpp boost/system/error_code.hpp],,
AC_CHECK_HEADERS([boost/shared_ptr.hpp boost/foreach.hpp boost/interprocess/sync/interprocess_upgradable_mutex.hpp boost/date_time/posix_time/posix_time_types.hpp boost/bind.hpp boost/function.hpp boost/asio/coroutine.hpp boost/asio.hpp boost/asio/ip/address.hpp boost/system/error_code.hpp],,
AC_MSG_ERROR([Missing required header files.]))
# clang can cause false positives with -Werror without -Qunused-arguments.
......
......@@ -423,6 +423,7 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence}
case '"':
/* impossible condition */
driver.error(driver.loc_, "Bad quote in \"" + raw + "\"");
break;
case '\\':
++pos;
if (pos >= len) {
......
......@@ -497,6 +497,7 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence}
case '"':
/* impossible condition */
driver.error(driver.loc_, "Bad quote in \"" + raw + "\"");
break;
case '\\':
++pos;
if (pos >= len) {
......
......@@ -1424,6 +1424,7 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence}
case '"':
/* impossible condition */
driver.error(driver.loc_, "Bad quote in \"" + raw + "\"");
break;
case '\\':
++pos;
if (pos >= len) {
......
......@@ -1445,6 +1445,7 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence}
case '"':
/* impossible condition */
driver.error(driver.loc_, "Bad quote in \"" + raw + "\"");
break;
case '\\':
++pos;
if (pos >= len) {
......
......@@ -225,7 +225,7 @@ IOFetch::getProtocol() const {
}
/// The function operator is implemented with the "stackless coroutine"
/// pattern; see internal/coroutine.h for details.
/// pattern; see boost/asio/coroutine.hpp for details.
void
IOFetch::operator()(boost::system::error_code ec, size_t length) {
......@@ -241,7 +241,7 @@ IOFetch::operator()(boost::system::error_code ec, size_t length) {
return;
}
CORO_REENTER (this) {
BOOST_ASIO_CORO_REENTER (this) {
/// Generate the upstream query and render it to wire format
/// This is done in a different scope to allow inline variable
......@@ -270,14 +270,14 @@ IOFetch::operator()(boost::system::error_code ec, size_t length) {
if (data_->socket->isOpenSynchronous()) {
data_->socket->open(data_->remote_snd.get(), *this);
} else {
CORO_YIELD data_->socket->open(data_->remote_snd.get(), *this);
BOOST_ASIO_CORO_YIELD data_->socket->open(data_->remote_snd.get(), *this);
}
do {
// Begin an asynchronous send, and then yield. When the send completes,
// we will resume immediately after this point.
data_->origin = ASIODNS_SEND_DATA;
CORO_YIELD data_->socket->asyncSend(data_->msgbuf->getData(),
BOOST_ASIO_CORO_YIELD data_->socket->asyncSend(data_->msgbuf->getData(),
data_->msgbuf->getLength(), data_->remote_snd.get(), *this);
// Now receive the response. Since TCP may not receive the entire
......@@ -304,13 +304,13 @@ IOFetch::operator()(boost::system::error_code ec, size_t length) {
data_->offset = 0; // First data into start of buffer
data_->received->clear(); // Clear the receive buffer
do {
CORO_YIELD data_->socket->asyncReceive(data_->staging,
static_cast<size_t>(STAGING_LENGTH),
data_->offset,
data_->remote_rcv.get(), *this);
BOOST_ASIO_CORO_YIELD data_->socket->asyncReceive(data_->staging,
static_cast<size_t>(STAGING_LENGTH),
data_->offset,
data_->remote_rcv.get(), *this);
} while (!data_->socket->processReceivedData(data_->staging, length,
data_->cumulative, data_->offset,
data_->expected, data_->received));
data_->cumulative, data_->offset,
data_->expected, data_->received));
} while (!data_->responseOK());
// Finished with this socket, so close it. This will not generate an
......
// Copyright (C) 2010-2015 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2010-2017 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
......@@ -11,7 +11,7 @@
#include <boost/shared_ptr.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <coroutine.h>
#include <boost/asio/coroutine.hpp>
#include <boost/system/error_code.hpp>
#include <asiolink/io_address.h>
......@@ -33,7 +33,7 @@ struct IOFetchData;
///
/// \param E Endpoint type to use.
class IOFetch : public coroutine {
class IOFetch : public boost::asio::coroutine {
public:
/// \brief Protocol to use on the fetch
enum Protocol {
......
......@@ -16,13 +16,14 @@
#include <string>
#include <exceptions/exceptions.h>
#include <coroutine.h>
#include <util/buffer.h>
#include <asiolink/io_error.h>
#include <asiolink/io_socket.h>
#include <boost/asio/coroutine.hpp>
namespace isc {
namespace asiolink {
......
......@@ -342,7 +342,7 @@ skipTo(std::istream& in, const std::string& file, int& line,
// error on the rest)?
std::string
strFromStringstream(std::istream& in, const std::string& file,
const int line, int& pos) throw (JSONError)
const int line, int& pos)
{
std::stringstream ss;
int c = in.get();
......@@ -608,7 +608,7 @@ Element::nameToType(const std::string& type_name) {
}
ElementPtr
Element::fromJSON(std::istream& in, bool preproc) throw(JSONError) {
Element::fromJSON(std::istream& in, bool preproc) {
int line = 1, pos = 1;
stringstream filtered;
......@@ -623,7 +623,6 @@ Element::fromJSON(std::istream& in, bool preproc) throw(JSONError) {
ElementPtr
Element::fromJSON(std::istream& in, const std::string& file_name, bool preproc)
throw(JSONError)
{
int line = 1, pos = 1;
stringstream filtered;
......@@ -635,7 +634,7 @@ Element::fromJSON(std::istream& in, const std::string& file_name, bool preproc)
ElementPtr
Element::fromJSON(std::istream& in, const std::string& file, int& line,
int& pos) throw(JSONError)
int& pos)
{
int c = 0;
ElementPtr element;
......
......@@ -427,8 +427,8 @@ public:
/// should be performed
/// @return An ElementPtr that contains the element(s) specified
/// in the given input stream.
static ElementPtr fromJSON(std::istream& in, bool preproc = false)
throw(JSONError);
/// @throw JSONError
static ElementPtr fromJSON(std::istream& in, bool preproc = false);
/// Creates an Element from the given input stream containing JSON
/// formatted data.
......@@ -439,9 +439,9 @@ public:
/// should be performed
/// @return An ElementPtr that contains the element(s) specified
/// in the given input stream.
/// @throw JSONError
static ElementPtr fromJSON(std::istream& in, const std::string& file_name,
bool preproc = false)
throw(JSONError);
bool preproc = false);
/// Creates an Element from the given input stream, where we keep
/// track of the location in the stream for error reporting.
......@@ -455,9 +455,9 @@ public:
/// @return An ElementPtr that contains the element(s) specified
/// in the given input stream.
// make this one private?
/// @throw JSONError
static ElementPtr fromJSON(std::istream& in, const std::string& file,
int& line, int &pos)
throw(JSONError);
int& line, int &pos);
/// Reads contents of specified file and interprets it as JSON.
///
......@@ -741,7 +741,7 @@ void merge(ElementPtr element, ConstElementPtr other);
/// @param level nesting level (default is 100, 0 means shallow copy,
/// negative means outbound and perhaps looping forever).
/// @return a pointer to a fresh copy
/// \throw raises a BadValue is a null pointer occurs.
/// @throw raises a BadValue is a null pointer occurs.
ElementPtr copy(ConstElementPtr from, int level = 100);
/// @brief Compares the data with other using unordered lists
......
......@@ -210,7 +210,7 @@ void
JSONFeed::receiveStartHandler() {
char c = getNextFromBuffer();
if (getNextEvent() != NEED_MORE_DATA_EVT) {
switch(getNextEvent()) {
switch (getNextEvent()) {
case START_EVT:
switch (c) {
case '\t':
......@@ -229,6 +229,7 @@ JSONFeed::receiveStartHandler() {
default:
feedFailure("invalid first character " + std::string(1, c));
break;
}
default:
......
// Copyright (C) 2010-2015 Internet Systems Consortium.
// Copyright (C) 2010-2017 Internet Systems Consortium.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
......@@ -186,9 +186,9 @@ namespace config {
// Public functions
//
// throw ModuleSpecError
ModuleSpec::ModuleSpec(ConstElementPtr module_spec_element,
const bool check)
throw(ModuleSpecError)
{
module_specification = module_spec_element;
......@@ -296,9 +296,9 @@ ModuleSpec::validateStatistics(ConstElementPtr data, const bool full,
return (validateSpecList(spec, data, full, errors));
}
// throw JSONError and ModuleSpecError
ModuleSpec
moduleSpecFromFile(const std::string& file_name, const bool check)
throw(JSONError, ModuleSpecError)
{
std::ifstream file;
......@@ -320,9 +320,9 @@ moduleSpecFromFile(const std::string& file_name, const bool check)
}
}
// throw JSONError and ModuleSpecError
ModuleSpec
moduleSpecFromFile(std::ifstream& in, const bool check)
throw(JSONError, ModuleSpecError)
{
ConstElementPtr module_spec_element = Element::fromJSON(in);
if (module_spec_element->contains("module_spec")) {
......
// Copyright (C) 2010-2015 Internet Systems Consortium.
// Copyright (C) 2010-2017 Internet Systems Consortium.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
......@@ -42,9 +42,9 @@ namespace isc { namespace config {
/// \param e The Element containing the data specification
/// \param check If false, the module specification in the file
/// is not checked to be of the correct form.
/// \throw ModuleSpecError
explicit ModuleSpec(isc::data::ConstElementPtr e,
const bool check = true)
throw(ModuleSpecError);
const bool check = true);
/// Returns the commands part of the specification as an
/// ElementPtr, returns an empty ElementPtr if there is none
......@@ -175,9 +175,9 @@ namespace isc { namespace config {
/// \param file_name The file to be opened and parsed
/// \param check If true, the module specification in the file
/// is checked to be of the correct form
/// \throw isc::data::JSONError and ModuleSpecError
ModuleSpec
moduleSpecFromFile(const std::string& file_name, const bool check = true)
throw(isc::data::JSONError, ModuleSpecError);
moduleSpecFromFile(const std::string& file_name, const bool check = true);
/// Creates a \c ModuleSpec instance from the given input
/// stream that contains the contents of a .spec file.
......@@ -187,9 +187,9 @@ namespace isc { namespace config {
/// \param in The std::istream containing the .spec file data
/// \param check If true, the module specification is checked
/// to be of the correct form
/// \throw isc::data::JSONError and ModuleSpecError
ModuleSpec
moduleSpecFromFile(std::ifstream& in, const bool check = true)
throw(isc::data::JSONError, ModuleSpecError);
moduleSpecFromFile(std::ifstream& in, const bool check = true);
} }
#endif // _DATA_DEF_H
......
......@@ -102,13 +102,13 @@ public:
switch (sizeof(T)) {
case 4:
buf.push_back((value >> 24) & 0xFF);
/* falls into */
/* falls through */
case 3:
buf.push_back((value >> 16) & 0xFF);
/* falls into */
/* falls through */
case 2:
buf.push_back((value >> 8) & 0xFF);
/* falls into */
/* falls through */
case 1:
buf.push_back(value & 0xFF);
break;
......
......@@ -47,13 +47,13 @@ public:
switch (sizeof(T)) {
case 4:
buf.push_back((value >> 24) & 0xFF);
/* falls into */
/* falls through */
case 3:
buf.push_back((value >> 16) & 0xFF);
/* falls into */
/* falls through */
case 2:
buf.push_back((value >> 8) & 0xFF);
/* falls into */
/* falls through */
case 1:
buf.push_back(value & 0xFF);
break;
......
// Copyright (C) 2011-2015 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2011-2017 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
......@@ -84,7 +84,7 @@ public:
}
/// \brief Destructor
~MessageException() throw() {}
~MessageException() {}
/// \brief Return Message ID
///
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment