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_/Pipe.hpp
|
||||||
network/virtual_/Socket.cpp
|
network/virtual_/Socket.cpp
|
||||||
network/virtual_/Socket.hpp
|
network/virtual_/Socket.hpp
|
||||||
|
network/virtual_/Interface.cpp
|
||||||
|
network/virtual_/Interface.hpp
|
||||||
parser/json/mapping/Deserializer.cpp
|
parser/json/mapping/Deserializer.cpp
|
||||||
parser/json/mapping/Deserializer.hpp
|
parser/json/mapping/Deserializer.hpp
|
||||||
parser/json/mapping/ObjectMapper.cpp
|
parser/json/mapping/ObjectMapper.cpp
|
||||||
@ -265,6 +267,8 @@ if(OATPP_BUILD_TESTS)
|
|||||||
test/parser/json/mapping/DTOMapperTest.hpp
|
test/parser/json/mapping/DTOMapperTest.hpp
|
||||||
test/network/virtual_/PipeTest.cpp
|
test/network/virtual_/PipeTest.cpp
|
||||||
test/network/virtual_/PipeTest.hpp
|
test/network/virtual_/PipeTest.hpp
|
||||||
|
test/network/virtual_/InterfaceTest.cpp
|
||||||
|
test/network/virtual_/InterfaceTest.hpp
|
||||||
)
|
)
|
||||||
target_link_libraries(oatppAllTests PRIVATE oatpp)
|
target_link_libraries(oatppAllTests PRIVATE oatpp)
|
||||||
set_target_properties(oatppAllTests PROPERTIES
|
set_target_properties(oatppAllTests PROPERTIES
|
||||||
|
@ -196,9 +196,8 @@ public:
|
|||||||
T result = node->data;
|
T result = node->data;
|
||||||
destroyNode(node);
|
destroyNode(node);
|
||||||
return result;
|
return result;
|
||||||
}else{
|
|
||||||
return T::empty();
|
|
||||||
}
|
}
|
||||||
|
throw std::runtime_error("[oatpp::collection::LinkedList::popFront()]: index out of bounds");
|
||||||
}
|
}
|
||||||
|
|
||||||
const T& getFirst() const{
|
const T& getFirst() const{
|
||||||
|
@ -25,9 +25,101 @@
|
|||||||
#ifndef oatpp_network_virtual__Interface_hpp
|
#ifndef oatpp_network_virtual__Interface_hpp
|
||||||
#define 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_ {
|
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(m_nonBlocking) {
|
||||||
if(pipe.m_buffer.availableToRead() > 0) {
|
if(pipe.m_buffer.availableToRead() > 0) {
|
||||||
result = pipe.m_buffer.read(data, count);
|
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;
|
result = oatpp::data::stream::Errors::ERROR_IO_WAIT_RETRY;
|
||||||
} else {
|
} else {
|
||||||
result = oatpp::data::stream::Errors::ERROR_IO_PIPE;
|
result = oatpp::data::stream::Errors::ERROR_IO_PIPE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::unique_lock<std::mutex> lock(pipe.m_mutex);
|
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_conditionWrite.notify_one();
|
||||||
pipe.m_conditionRead.wait(lock);
|
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(m_nonBlocking) {
|
||||||
if(pipe.m_buffer.availableToWrite() > 0) {
|
if(pipe.m_buffer.availableToWrite() > 0) {
|
||||||
result = pipe.m_buffer.write(data, count);
|
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;
|
result = oatpp::data::stream::Errors::ERROR_IO_WAIT_RETRY;
|
||||||
} else {
|
} else {
|
||||||
result = oatpp::data::stream::Errors::ERROR_IO_PIPE;
|
result = oatpp::data::stream::Errors::ERROR_IO_PIPE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::unique_lock<std::mutex> lock(pipe.m_mutex);
|
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_conditionRead.notify_one();
|
||||||
pipe.m_conditionWrite.wait(lock);
|
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);
|
result = pipe.m_buffer.write(data, count);
|
||||||
} else {
|
} else {
|
||||||
result = oatpp::data::stream::Errors::ERROR_IO_PIPE;
|
result = oatpp::data::stream::Errors::ERROR_IO_PIPE;
|
||||||
|
@ -77,7 +77,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_alive;
|
bool m_open;
|
||||||
Writer m_writer;
|
Writer m_writer;
|
||||||
Reader m_reader;
|
Reader m_reader;
|
||||||
oatpp::data::buffer::FIFOBuffer m_buffer;
|
oatpp::data::buffer::FIFOBuffer m_buffer;
|
||||||
@ -87,7 +87,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
Pipe()
|
Pipe()
|
||||||
: m_alive(true)
|
: m_open(true)
|
||||||
, m_writer(this)
|
, m_writer(this)
|
||||||
, m_reader(this)
|
, m_reader(this)
|
||||||
{}
|
{}
|
||||||
@ -104,6 +104,10 @@ public:
|
|||||||
return &m_reader;
|
return &m_reader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void close() {
|
||||||
|
m_open = false;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}}}
|
}}}
|
||||||
|
@ -25,40 +25,42 @@
|
|||||||
#ifndef oatpp_network_virtual__Socket_hpp
|
#ifndef oatpp_network_virtual__Socket_hpp
|
||||||
#define oatpp_network_virtual__Socket_hpp
|
#define oatpp_network_virtual__Socket_hpp
|
||||||
|
|
||||||
#include "Pipe.hpp"
|
#include "./Pipe.hpp"
|
||||||
|
|
||||||
namespace oatpp { namespace network { namespace virtual_ {
|
namespace oatpp { namespace network { namespace virtual_ {
|
||||||
|
|
||||||
class Socket : public oatpp::base::Controllable, public oatpp::data::stream::IOStream {
|
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:
|
private:
|
||||||
std::shared_ptr<Pipe::Reader> m_pipeReader;
|
std::shared_ptr<Pipe> m_pipeIn;
|
||||||
std::shared_ptr<Pipe::Writer> m_pipeWriter;
|
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:
|
public:
|
||||||
|
|
||||||
os::io::Library::v_size read(void *data, os::io::Library::v_size count) override {
|
static std::shared_ptr<Socket> createShared(const std::shared_ptr<Pipe>& pipeIn, const std::shared_ptr<Pipe>& pipeOut) {
|
||||||
if(m_pipeReader) {
|
return std::make_shared<Socket>(pipeIn, pipeOut);
|
||||||
return m_pipeReader->read(data, count);
|
|
||||||
}
|
}
|
||||||
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 {
|
os::io::Library::v_size write(const void *data, os::io::Library::v_size count) override {
|
||||||
if(m_pipeWriter) {
|
return m_pipeOut->getWriter()->write(data, count);
|
||||||
return m_pipeWriter->write(data, count);
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isConnected() {
|
|
||||||
return m_pipeReader && m_pipeWriter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void close() {
|
void close() {
|
||||||
m_pipeReader.reset();
|
m_pipeIn->close();
|
||||||
m_pipeWriter.reset();
|
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() {
|
bool PipeTest::onRun() {
|
||||||
|
Loading…
Reference in New Issue
Block a user