From: Christian Kamm Date: Thu, 17 Jan 2019 09:16:44 +0000 (+0100) Subject: SocketAPI OSX: Forbid further sends on connectionDidDie X-Git-Tag: archive/raspbian/3.16.7-1_deb13u1+rpi1~1^2~12^2~21^2~468^2~323 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=0eebd77d2cfce7e98c8fdf9b64a92da46524aa64;p=nextcloud-desktop.git SocketAPI OSX: Forbid further sends on connectionDidDie Also release the remote end immediately. --- 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) {