mirror of
https://gitee.com/zyjblog/oatpp.git
synced 2024-12-22 22:16:37 +08:00
network::virtual_::InterfaceTest prepared
This commit is contained in:
parent
f132bdd33f
commit
ea215059ad
@ -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
|
||||
|
@ -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{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}}}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
};
|
||||
|
38
test/network/virtual_/InterfaceTest.cpp
Normal file
38
test/network/virtual_/InterfaceTest.cpp
Normal 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;
|
||||
}
|
||||
|
||||
}}}}
|
40
test/network/virtual_/InterfaceTest.hpp
Normal file
40
test/network/virtual_/InterfaceTest.hpp
Normal 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 */
|
@ -131,8 +131,6 @@ namespace {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool PipeTest::onRun() {
|
||||
|
Loading…
Reference in New Issue
Block a user