From 0eebd77d2cfce7e98c8fdf9b64a92da46524aa64 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Thu, 17 Jan 2019 10:16:44 +0100 Subject: [PATCH] SocketAPI OSX: Forbid further sends on connectionDidDie Also release the remote end immediately. --- src/gui/socketapisocket_mac.mm | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/gui/socketapisocket_mac.mm b/src/gui/socketapisocket_mac.mm index 554447cf1..f018ac752 100644 --- a/src/gui/socketapisocket_mac.mm +++ b/src/gui/socketapisocket_mac.mm @@ -42,9 +42,13 @@ public: SocketApiSocketPrivate(NSDistantObject *remoteEnd); ~SocketApiSocketPrivate(); + // release remoteEnd + void disconnectRemote(); + NSDistantObject *remoteEnd; LocalEnd *localEnd; QByteArray inBuffer; + bool isRemoteDisconnected = false; }; class SocketApiServerPrivate @@ -80,8 +84,10 @@ public: - (void)connectionDidDie:(NSNotification*)notification { #pragma unused(notification) - if (_wrapper) + if (_wrapper) { + _wrapper->disconnectRemote(); emit _wrapper->q_ptr->disconnected(); + } } @end @@ -133,8 +139,11 @@ qint64 SocketApiSocket::readData(char *data, qint64 maxlen) qint64 SocketApiSocket::writeData(const char *data, qint64 len) { + Q_D(SocketApiSocket); + if (d->isRemoteDisconnected) + return -1; + @try { - Q_D(SocketApiSocket); // FIXME: The NSConnection will make this block unless the function is marked as "oneway" // in the protocol. This isn't async and reduces our performances but this currectly avoids // a Mach queue deadlock during requests bursts of the legacy OwnCloudFinder extension. @@ -143,6 +152,7 @@ qint64 SocketApiSocket::writeData(const char *data, qint64 len) return len; } @catch(NSException* e) { // connectionDidDie can be notified too late, also interpret any sending exception as a disconnection. + d->disconnectRemote(); emit disconnected(); return -1; } @@ -174,12 +184,22 @@ SocketApiSocketPrivate::SocketApiSocketPrivate(NSDistantObject SocketApiSocketPrivate::~SocketApiSocketPrivate() { - [remoteEnd release]; + disconnectRemote(); + // The DO vended localEnd might still be referenced by the connection localEnd.wrapper = nil; [localEnd release]; } +void SocketApiSocketPrivate::disconnectRemote() +{ + if (isRemoteDisconnected) + return; + isRemoteDisconnected = true; + + [remoteEnd release]; +} + SocketApiServer::SocketApiServer() : d_ptr(new SocketApiServerPrivate) { -- 2.30.2