Skip to content

Commit 23f79ba

Browse files
committed
cancel closes by default
1 parent ba1b428 commit 23f79ba

File tree

12 files changed

+495
-369
lines changed

12 files changed

+495
-369
lines changed

.vscode/launch.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"type": "lldb",
1010
"request": "launch",
1111
"program": "${workspaceFolder}/bin/frontend_cryptoTools",
12-
"args": ["-u", "15", "-loop", "100"],
12+
"args": ["-u","-loop", "100"],
1313
"stopAtEntry": false,
1414
"cwd": "${workspaceFolder}",
1515
"environment": [],

cryptoTools/Network/Channel.cpp

+59-42
Original file line numberDiff line numberDiff line change
@@ -74,27 +74,34 @@ namespace osuCrypto {
7474
std::string remoteName)
7575
:
7676
mIos(endpoint.getIOService()),
77-
mWork(new boost::asio::io_service::work(endpoint.getIOService().mIoService)),
77+
mWork(endpoint.getIOService(), "Channel:" + endpoint.mBase->mName + "." + localName
78+
+ (endpoint.mBase->mMode == SessionMode::Server ? " (server)" : " (client)")),
7879
mSession(endpoint.mBase),
7980
mRemoteName(remoteName),
8081
mLocalName(localName),
8182
mChannelRefCount(1),
8283
mStrand(endpoint.getIOService().mIoService.get_executor())
8384
{
85+
std::lock_guard<std::mutex> lock(mIos.mWorkerMtx);
86+
mIos.mChannels.insert(this);
8487
}
8588

8689
ChannelBase::ChannelBase(IOService& ios, SocketInterface* sock)
8790
:
8891
mIos(ios),
89-
mWork(new boost::asio::io_service::work(ios.mIoService)),
92+
mWork(ios, "Channel: SocketInterface." + std::to_string((u64)sock) ),
9093
mChannelRefCount(1),
9194
mHandle(sock),
9295
mStrand(ios.mIoService.get_executor())
9396
{
97+
std::lock_guard<std::mutex> lock(mIos.mWorkerMtx);
98+
mIos.mChannels.insert(this);
9499
}
95100

96101
ChannelBase::~ChannelBase()
97102
{
103+
std::lock_guard<std::mutex> lock(mIos.mWorkerMtx);
104+
mIos.mChannels.erase(mIos.mChannels.find(this));
98105
assert(mChannelRefCount ==0);
99106
}
100107

@@ -338,7 +345,7 @@ namespace osuCrypto {
338345

339346
void StartSocketOp::connectCallback(const error_code& ec)
340347
{
341-
IF_LOG(mChl->mLog.push("calling StartSocketOp::asyncConnectToServer(...) cb1 "));
348+
//IF_LOG(mChl->mLog.push("calling StartSocketOp::asyncConnectToServer(...) cb1 "));
342349

343350
boost::asio::dispatch(mStrand, [this, ec] {
344351
// lout << "calling StartSocketOp::asyncConnectToServer(...) cb1 " << time() << std::endl;
@@ -366,11 +373,11 @@ namespace osuCrypto {
366373

367374
if (ec2)
368375
{
376+
IF_LOG(
369377
auto msg = "async connect. Failed to set option ~ ec=" + ec2.message() + "\n"
370378
+ " isOpen=" + std::to_string(sock.is_open())
371379
+ " stopped=" + std::to_string(canceled());
372-
373-
IF_LOG(mChl->mLog.push(msg));
380+
mChl->mLog.push(msg));
374381

375382
// retry.
376383
retryConnect(ec2);
@@ -451,11 +458,13 @@ namespace osuCrypto {
451458
{
452459
auto& sock = mSock->mSock;
453460

454-
auto msg = "async connect. Failed to send ConnectionString ~ ec=" + ec.message() + "\n"
461+
IF_LOG(
462+
auto msg = "async connect. Failed to send ConnectionString ~ ec=" + ec.message() + "\n"
455463
+ " isOpen=" + std::to_string(sock.is_open())
456464
+ " canceled=" + std::to_string(canceled());
457465

458-
IF_LOG(mChl->mLog.push(msg));
466+
mChl->mLog.push(msg)
467+
);
459468

460469
// Unknown issue where we connect but then the pipe is broken.
461470
// Simply retrying seems to be a workaround.
@@ -474,19 +483,11 @@ namespace osuCrypto {
474483

475484
void osuCrypto::StartSocketOp::retryConnect(const error_code& ec)
476485
{
477-
478-
479486
error_code ec2;
480487
mSock->mSock.close(ec2);
481488

482-
IF_LOG(if (ec2)
483-
mChl->mLog.push("error closing boost socket (3), ec = " + ec2.message()));
484-
485489
auto count = static_cast<u64>(mBackoff);
486-
487490
mTimer.expires_from_now(boost::posix_time::millisec(count));
488-
489-
490491
mBackoff = std::min(mBackoff * 1.2, 1000.0);
491492
if (mBackoff >= 1000.0)
492493
{
@@ -527,16 +528,18 @@ namespace osuCrypto {
527528

528529
Channel& Channel::operator=(Channel&& move)
529530
{
530-
if(mBase)
531-
--mBase->mChannelRefCount;
531+
if(mBase && --mBase->mChannelRefCount == 0)
532+
mBase->close();
533+
532534
mBase = std::move(move.mBase);
533535
return *this;
534536
}
535537

536538
Channel& Channel::operator=(const Channel& copy)
537539
{
538-
if(mBase)
539-
--mBase->mChannelRefCount;
540+
if(mBase && --mBase->mChannelRefCount == 0)
541+
mBase->close();
542+
540543
mBase = copy.mBase;
541544
if(mBase)
542545
++mBase->mChannelRefCount;
@@ -625,9 +628,9 @@ namespace osuCrypto {
625628
if (mBase) mBase->close();
626629
}
627630

628-
void Channel::cancel()
631+
void Channel::cancel(bool close)
629632
{
630-
if (mBase) mBase->cancel();
633+
if (mBase) mBase->cancel(close);
631634
}
632635

633636
void Channel::asyncClose(std::function<void()> completionHandle)
@@ -636,9 +639,9 @@ namespace osuCrypto {
636639
else completionHandle();
637640
}
638641

639-
void Channel::asyncCancel(std::function<void()> completionHandle)
642+
void Channel::asyncCancel(std::function<void()> completionHandle, bool close)
640643
{
641-
if (mBase) mBase->asyncCancel(std::move(completionHandle));
644+
if (mBase) mBase->asyncCancel(std::move(completionHandle), close);
642645
else completionHandle();
643646
}
644647

@@ -668,7 +671,7 @@ namespace osuCrypto {
668671
#else
669672
char str= 0;
670673
#endif
671-
mRecvQueue.push_back(std::move(op));
674+
mRecvQueue.push_back(std::forward<SBO_ptr<details::RecvOperation>>(op));
672675
auto lifetime = shared_from_this();
673676

674677
// a strand is like a lock. Stuff posted (or dispatched) to a strand will be executed sequentially
@@ -680,16 +683,21 @@ namespace osuCrypto {
680683
bool available = recvSocketAvailable();
681684
bool startRecving = hasItems && available;
682685

683-
LOG_MSG("recv queuing "+str+": start = " + std::to_string(startRecving) + " = " + std::to_string(hasItems) + " && " + std::to_string(available));
684686
// the queue must be guarded from concurrent access, so add the op within the strand
685687
// queue up the operation.
686688
if (startRecving)
687689
{
690+
assert(mStatus != Channel::Status::Closed);
691+
688692
// ok, so there isn't any recv operations currently underway. Lets kick off the first one. Subsequent recvs
689693
// will be kicked off at the completion of this operation.
690694
mRecvLoopLifetime = std::move(lifetime);
691695
asyncPerformRecv();
692696
}
697+
else
698+
{
699+
LOG_MSG("recv defered "+str+": " + std::to_string(hasItems) + " && " + std::to_string(available));
700+
}
693701
});
694702
}
695703

@@ -703,23 +711,25 @@ namespace osuCrypto {
703711
char str = 0;
704712
#endif
705713

706-
mSendQueue.push_back(std::move(op));
714+
mSendQueue.push_back(std::forward<SBO_ptr<details::SendOperation>>(op));
707715
auto lifetime = shared_from_this();
708716

709717
// a strand is like a lock. Stuff posted (or dispatched) to a strand will be executed sequentially
710718
boost::asio::dispatch(mStrand, [this, str, lifetime = std::move(lifetime)]() mutable
711719
{
712720
auto hasItems = (mSendQueue.isEmpty() == false);
713-
auto avaliable = sendSocketAvailable();
714-
auto startSending = hasItems && avaliable;
715-
716-
LOG_MSG("send queuing "+str+": start = " + std::to_string(startSending) + " = " + std::to_string(hasItems)
717-
+ " & " + std::to_string(avaliable));
721+
auto available = sendSocketAvailable();
722+
auto startSending = hasItems && available;
718723

719724
if (startSending)
720725
{
726+
assert(mStatus != Channel::Status::Closed);
721727
mSendLoopLifetime = std::move(lifetime);
722728
asyncPerformSend();
729+
}
730+
else
731+
{
732+
LOG_MSG("send defered "+str+": " + std::to_string(hasItems) + " && " + std::to_string(available));
723733
}
724734
});
725735
}
@@ -830,17 +840,17 @@ namespace osuCrypto {
830840
mIos.printError(s);
831841
}
832842

833-
void ChannelBase::cancel()
843+
void ChannelBase::cancel(bool close)
834844
{
835845
std::promise<void> prom;
836846
asyncCancel([&]() {
837847
prom.set_value();
838-
});
848+
}, close);
839849

840850
prom.get_future().get();
841851
}
842852

843-
void ChannelBase::asyncCancel(std::function<void()> completionHandle)
853+
void ChannelBase::asyncCancel(std::function<void()> completionHandle, bool close)
844854
{
845855
LOG_MSG("cancel()");
846856

@@ -851,27 +861,34 @@ namespace osuCrypto {
851861
std::atomic<u32> mCount;
852862
std::function<void()> mFn;
853863
std::shared_ptr<ChannelBase> mLifetime;
854-
CancelState(std::function<void()>&& fn, std::shared_ptr<ChannelBase>&& p)
864+
bool mClose;
865+
CancelState(std::function<void()>&& fn, std::shared_ptr<ChannelBase>&& p, bool close)
855866
: mCount(2)
856867
, mFn(std::move(fn))
857-
, mLifetime(std::move(p)){}
868+
, mLifetime(std::move(p))
869+
, mClose(close)
870+
{}
858871
};
859872

860-
auto state = std::make_shared<CancelState>(std::move(completionHandle), shared_from_this());
861-
//auto lifetime = shared_from_this();
862-
boost::asio::dispatch(mStrand, [this, state]() mutable{
873+
auto state = std::make_shared<CancelState>(std::move(completionHandle), shared_from_this(), close);
874+
875+
boost::asio::post(mStrand, [this, state]() mutable{
876+
863877
mStatus = Channel::Status::Canceling;
878+
864879
auto ec = boost::system::errc::make_error_code(boost::system::errc::operation_canceled);
865880
mRecvCancelNew = true;
866881
mSendCancelNew = true;
867882

868-
869883
auto cb = [this,state]() mutable{
870884
if(--state->mCount == 0)
871885
{
872886
LOG_MSG("cancel callback.");
887+
888+
if(state->mClose)
889+
mStatus = Channel::Status::Closed;
890+
873891
mHandle.reset(nullptr);
874-
mWork.reset(nullptr);
875892
state->mFn();
876893
}
877894
};
@@ -948,7 +965,7 @@ namespace osuCrypto {
948965
mHandle->close();
949966
}
950967
mHandle.reset(nullptr);
951-
mWork.reset(nullptr);
968+
mWork.reset();
952969
LOG_MSG("Closed");
953970

954971
auto c = std::move(ch);

cryptoTools/Network/Channel.h

+6-6
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#include <cryptoTools/Common/Defines.h>
44
#include <cryptoTools/Network/IoBuffer.h>
55
#include <cryptoTools/Network/SocketAdapter.h>
6-
6+
#include <cryptoTools/Network/util.h>
77

88
#ifdef ENABLE_NET_LOG
99
#include <cryptoTools/Common/Log.h>
@@ -302,11 +302,11 @@ namespace osuCrypto {
302302
void close();
303303

304304
// Aborts all current operations (connect, send, receive).
305-
void cancel();
305+
void cancel(bool close = true);
306306

307307
void asyncClose(std::function<void()> completionHandle);
308308

309-
void asyncCancel(std::function<void()> completionHandle);
309+
void asyncCancel(std::function<void()> completionHandle, bool close = true);
310310

311311

312312
enum class Status { Normal, Closing, Closed, Canceling};
@@ -486,7 +486,7 @@ namespace osuCrypto {
486486
~ChannelBase();
487487

488488
IOService& mIos;
489-
std::unique_ptr<boost::asio::io_service::work> mWork;
489+
Work mWork;
490490
std::unique_ptr<StartSocketOp> mStartOp;
491491

492492
std::shared_ptr<SessionBase> mSession;
@@ -516,9 +516,9 @@ namespace osuCrypto {
516516
void cancelSendQueue(const error_code& ec);
517517

518518
void close();
519-
void cancel();
519+
void cancel(bool close);
520520
void asyncClose(std::function<void()> completionHandle);
521-
void asyncCancel(std::function<void()> completionHandle);
521+
void asyncCancel(std::function<void()> completionHandle, bool close);
522522

523523
IOService& getIOService() { return mIos; }
524524

0 commit comments

Comments
 (0)