network::virtual_::InterfaceTest prepared

This commit is contained in:
lganzzzo 2018-11-15 12:01:11 +02:00
parent f132bdd33f
commit ea215059ad
9 changed files with 208 additions and 31 deletions

View File

@ -108,6 +108,8 @@ add_library(oatpp
network/virtual_/Pipe.hpp
network/virtual_/Socket.cpp
network/virtual_/Socket.hpp
network/virtual_/Interface.cpp
network/virtual_/Interface.hpp
parser/json/mapping/Deserializer.cpp
parser/json/mapping/Deserializer.hpp
parser/json/mapping/ObjectMapper.cpp
@ -265,6 +267,8 @@ if(OATPP_BUILD_TESTS)
test/parser/json/mapping/DTOMapperTest.hpp
test/network/virtual_/PipeTest.cpp
test/network/virtual_/PipeTest.hpp
test/network/virtual_/InterfaceTest.cpp
test/network/virtual_/InterfaceTest.hpp
)
target_link_libraries(oatppAllTests PRIVATE oatpp)
set_target_properties(oatppAllTests PROPERTIES

View File

@ -196,9 +196,8 @@ public:
T result = node->data;
destroyNode(node);
return result;
}else{
return T::empty();
}
throw std::runtime_error("[oatpp::collection::LinkedList::popFront()]: index out of bounds");
}
const T& getFirst() const{

View File

@ -25,9 +25,101 @@
#ifndef oatpp_network_virtual__Interface_hpp
#define oatpp_network_virtual__Interface_hpp
#include "./Socket.hpp"
#include "oatpp/core/collection/LinkedList.hpp"
namespace oatpp { namespace network { namespace virtual_ {
class Interface : public oatpp::base::Controllable {
public:
class ConnectionSubmission {
private:
std::shared_ptr<Socket> m_socket;
std::mutex m_mutex;
std::condition_variable m_condition;
bool m_pending;
public:
ConnectionSubmission()
: m_pending(true)
{}
void setSocket(const std::shared_ptr<Socket>& socket) {
m_socket = socket;
m_condition.notify_one();
}
std::shared_ptr<Socket> getSocket() {
std::unique_lock<std::mutex> lock(m_mutex);
while (!m_socket && m_pending) {
m_condition.wait(lock);
}
return m_socket;
}
std::shared_ptr<Socket> getSocketNonBlocking() {
return m_socket;
}
bool isPending() {
return m_pending;
}
};
private:
std::shared_ptr<Socket> acceptSubmission(const std::shared_ptr<ConnectionSubmission>& submission) {
auto pipeIn = Pipe::createShared();
auto pipeOut = Pipe::createShared();
auto serverSocket = Socket::createShared(pipeIn, pipeOut);
auto clientSocket = Socket::createShared(pipeOut, pipeIn);
submission->setSocket(clientSocket);
return serverSocket;
}
private:
std::mutex m_mutex;
std::condition_variable m_condition;
oatpp::collection::LinkedList<std::shared_ptr<ConnectionSubmission>> m_submissions;
public:
std::shared_ptr<ConnectionSubmission> connect() {
auto submission = std::make_shared<ConnectionSubmission>();
{
std::lock_guard<std::mutex> lock(m_mutex);
m_submissions.pushBack(submission);
}
m_condition.notify_one();
return submission;
}
std::shared_ptr<Socket> accept() {
std::unique_lock<std::mutex> lock(m_mutex);
while (m_submissions.getFirstNode() == nullptr) {
m_condition.wait(lock);
}
return acceptSubmission(m_submissions.popFront());
}
std::shared_ptr<Socket> acceptNonBlocking() {
std::lock_guard<std::mutex> lock(m_mutex);
if(m_submissions.getFirstNode() == nullptr) {
return acceptSubmission(m_submissions.popFront());
}
return nullptr;
}
};
}}}

View File

@ -34,14 +34,14 @@ os::io::Library::v_size Pipe::Reader::read(void *data, os::io::Library::v_size c
if(m_nonBlocking) {
if(pipe.m_buffer.availableToRead() > 0) {
result = pipe.m_buffer.read(data, count);
} else if(pipe.m_alive) {
} else if(pipe.m_open) {
result = oatpp::data::stream::Errors::ERROR_IO_WAIT_RETRY;
} else {
result = oatpp::data::stream::Errors::ERROR_IO_PIPE;
}
} else {
std::unique_lock<std::mutex> lock(pipe.m_mutex);
while (pipe.m_buffer.availableToRead() == 0 && pipe.m_alive) {
while (pipe.m_buffer.availableToRead() == 0 && pipe.m_open) {
pipe.m_conditionWrite.notify_one();
pipe.m_conditionRead.wait(lock);
}
@ -66,18 +66,18 @@ os::io::Library::v_size Pipe::Writer::write(const void *data, os::io::Library::v
if(m_nonBlocking) {
if(pipe.m_buffer.availableToWrite() > 0) {
result = pipe.m_buffer.write(data, count);
} else if(pipe.m_alive) {
} else if(pipe.m_open) {
result = oatpp::data::stream::Errors::ERROR_IO_WAIT_RETRY;
} else {
result = oatpp::data::stream::Errors::ERROR_IO_PIPE;
}
} else {
std::unique_lock<std::mutex> lock(pipe.m_mutex);
while (pipe.m_buffer.availableToWrite() == 0 && pipe.m_alive) {
while (pipe.m_buffer.availableToWrite() == 0 && pipe.m_open) {
pipe.m_conditionRead.notify_one();
pipe.m_conditionWrite.wait(lock);
}
if (pipe.m_alive && pipe.m_buffer.availableToWrite() > 0) {
if (pipe.m_open && pipe.m_buffer.availableToWrite() > 0) {
result = pipe.m_buffer.write(data, count);
} else {
result = oatpp::data::stream::Errors::ERROR_IO_PIPE;

View File

@ -77,7 +77,7 @@ public:
};
private:
bool m_alive;
bool m_open;
Writer m_writer;
Reader m_reader;
oatpp::data::buffer::FIFOBuffer m_buffer;
@ -87,7 +87,7 @@ private:
public:
Pipe()
: m_alive(true)
: m_open(true)
, m_writer(this)
, m_reader(this)
{}
@ -104,6 +104,10 @@ public:
return &m_reader;
}
void close() {
m_open = false;
}
};
}}}

View File

@ -25,40 +25,42 @@
#ifndef oatpp_network_virtual__Socket_hpp
#define oatpp_network_virtual__Socket_hpp
#include "Pipe.hpp"
#include "./Pipe.hpp"
namespace oatpp { namespace network { namespace virtual_ {
class Socket : public oatpp::base::Controllable, public oatpp::data::stream::IOStream {
public:
OBJECT_POOL(Socket_Pool, Socket, 32)
SHARED_OBJECT_POOL(Shared_Socket_Pool, Socket, 32)
private:
std::shared_ptr<Pipe::Reader> m_pipeReader;
std::shared_ptr<Pipe::Writer> m_pipeWriter;
std::shared_ptr<Pipe> m_pipeIn;
std::shared_ptr<Pipe> m_pipeOut;
public:
Socket(const std::shared_ptr<Pipe>& pipeIn, const std::shared_ptr<Pipe>& pipeOut)
: m_pipeIn(pipeIn)
, m_pipeOut(pipeOut)
{}
public:
os::io::Library::v_size read(void *data, os::io::Library::v_size count) override {
if(m_pipeReader) {
return m_pipeReader->read(data, count);
static std::shared_ptr<Socket> createShared(const std::shared_ptr<Pipe>& pipeIn, const std::shared_ptr<Pipe>& pipeOut) {
return std::make_shared<Socket>(pipeIn, pipeOut);
}
return -1;
~Socket() {
close();
}
os::io::Library::v_size read(void *data, os::io::Library::v_size count) override {
return m_pipeIn->getReader()->read(data, count);
}
os::io::Library::v_size write(const void *data, os::io::Library::v_size count) override {
if(m_pipeWriter) {
return m_pipeWriter->write(data, count);
}
return -1;
}
bool isConnected() {
return m_pipeReader && m_pipeWriter;
return m_pipeOut->getWriter()->write(data, count);
}
void close() {
m_pipeReader.reset();
m_pipeWriter.reset();
m_pipeIn->close();
m_pipeOut->close();
m_pipeIn.reset();
m_pipeOut.reset();
}
};

View File

@ -0,0 +1,38 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi, <lganzzzo@gmail.com>
*
* Licensed 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 "InterfaceTest.hpp"
namespace oatpp { namespace test { namespace network { namespace virtual_ {
namespace {
}
bool InterfaceTest::onRun() {
return true;
}
}}}}

View File

@ -0,0 +1,40 @@
/***************************************************************************
*
* Project _____ __ ____ _ _
* ( _ ) /__\ (_ _)_| |_ _| |_
* )(_)( /(__)\ )( (_ _)(_ _)
* (_____)(__)(__)(__) |_| |_|
*
*
* Copyright 2018-present, Leonid Stryzhevskyi, <lganzzzo@gmail.com>
*
* Licensed 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.
*
***************************************************************************/
#ifndef oatpp_test_network_virtual__InterfaceTest_hpp
#define oatpp_test_network_virtual__InterfaceTest_hpp
#include "oatpp/test/UnitTest.hpp"
namespace oatpp { namespace test { namespace network { namespace virtual_ {
class InterfaceTest : public UnitTest {
public:
InterfaceTest():UnitTest("TEST[network::virtual_::InterfaceTest]"){}
bool onRun() override;
};
}}}}
#endif /* oatpp_test_network_virtual__InterfaceTest_hpp */

View File

@ -131,8 +131,6 @@ namespace {
}
}
bool PipeTest::onRun() {