SocketApiSocketPrivate(NSDistantObject <ChannelProtocol> *remoteEnd);
~SocketApiSocketPrivate();
+ // release remoteEnd
+ void disconnectRemote();
+
NSDistantObject <ChannelProtocol> *remoteEnd;
LocalEnd *localEnd;
QByteArray inBuffer;
+ bool isRemoteDisconnected = false;
};
class SocketApiServerPrivate
- (void)connectionDidDie:(NSNotification*)notification
{
#pragma unused(notification)
- if (_wrapper)
+ if (_wrapper) {
+ _wrapper->disconnectRemote();
emit _wrapper->q_ptr->disconnected();
+ }
}
@end
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.
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;
}
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)
{