Skip to content
This repository was archived by the owner on Mar 26, 2023. It is now read-only.

Fixed the crash with async disconnect in StreamSession. #348

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions stream/Apple/StreamSession.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,10 @@ namespace videocore {
StreamSessionCallback_T m_callback;
StreamStatus_T m_status;

int m_outSocket;

int m_outSocket;
dispatch_queue_t m_serialQueue;
};
}
}



#endif /* defined(__videocore__StreamSession__) */
#endif /* defined(__videocore__StreamSession__) */
83 changes: 51 additions & 32 deletions stream/Apple/StreamSession.mm
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,19 @@ - (void) stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
m_streamCallback = [[NSStreamCallback alloc] init];
SCB(m_streamCallback).session = this;
m_serialQueue = dispatch_queue_create("com.videocore.network", DISPATCH_QUEUE_SERIAL);
}

StreamSession::~StreamSession()
{
disconnect();
[SCB(m_streamCallback) release];
if (m_serialQueue) {
#if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000
dispatch_release(m_serialQueue);
#endif
m_serialQueue = nil;
}
}

void
Expand All @@ -88,50 +95,55 @@ - (void) stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
&readStream,
&writeStream);

CFReadStreamSetProperty(readStream,
kCFStreamPropertyShouldCloseNativeSocket,
kCFBooleanTrue);
CFWriteStreamSetProperty(writeStream,
kCFStreamPropertyShouldCloseNativeSocket,
kCFBooleanTrue);

m_inputStream = (NSInputStream*)readStream;
m_outputStream = (NSOutputStream*)writeStream;


dispatch_queue_t queue = dispatch_queue_create("com.videocore.network", 0);

if(m_inputStream && m_outputStream) {
dispatch_async(queue, ^{
if (m_inputStream && m_outputStream) {
dispatch_async(m_serialQueue, ^{
this->startNetwork();
});
}
else {
nsStreamCallback(nullptr, NSStreamEventErrorOccurred);
}
dispatch_release(queue);
}

}

void
StreamSession::disconnect()
{
if(m_outputStream) {
//if(m_runLoop) {
// [NSOS(m_outputStream) removeFromRunLoop:NSRL(m_runLoop) forMode:NSDefaultRunLoopMode];
//}
[NSOS(m_outputStream) close];
[NSOS(m_outputStream) release];
m_outputStream = nullptr;
}
if(m_inputStream) {
//if(m_runLoop) {
// [NSOS(m_inputStream) removeFromRunLoop:NSRL(m_runLoop) forMode:NSDefaultRunLoopMode];
//}
[NSIS(m_inputStream) close];
[NSIS(m_inputStream) release];
m_inputStream = nullptr;
}

if(m_runLoop) {
CFRunLoopStop([NSRL(m_runLoop) getCFRunLoop]);
[(id)m_runLoop release];
m_runLoop = nullptr;
}
dispatch_sync(m_serialQueue, ^{
if (m_outputStream) {
if (m_runLoop) {
[NSOS(m_outputStream) removeFromRunLoop:NSRL(m_runLoop) forMode:NSDefaultRunLoopMode];
}
[NSOS(m_outputStream) close];
[NSOS(m_outputStream) release];
m_outputStream = nullptr;
}

if (m_inputStream) {
if (m_runLoop) {
[NSOS(m_inputStream) removeFromRunLoop:NSRL(m_runLoop) forMode:NSDefaultRunLoopMode];
}
[NSIS(m_inputStream) close];
[NSIS(m_inputStream) release];
m_inputStream = nullptr;
}

if (m_runLoop) {
CFRunLoopStop([NSRL(m_runLoop) getCFRunLoop]);
[(id)m_runLoop release];
m_runLoop = nullptr;
}
});
}

ssize_t
Expand Down Expand Up @@ -180,6 +192,7 @@ - (void) stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
}
m_callback(*this, status);
}

void
StreamSession::nsStreamCallback(void* stream, unsigned event)
{
Expand Down Expand Up @@ -218,16 +231,22 @@ - (void) stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
StreamSession::startNetwork()
{
m_runLoop = [NSRunLoop currentRunLoop];
[(NSRunLoop *)m_runLoop retain];

[NSIS(m_inputStream) setDelegate:SCB(m_streamCallback)];
[NSIS(m_inputStream) scheduleInRunLoop:NSRL(m_runLoop) forMode:NSDefaultRunLoopMode];
[NSOS(m_outputStream) setDelegate:SCB(m_streamCallback)];
[NSOS(m_outputStream) scheduleInRunLoop:NSRL(m_runLoop) forMode:NSDefaultRunLoopMode];
[NSOS(m_outputStream) open];
[NSIS(m_inputStream) open];

[(id)m_runLoop retain];
[NSRL(m_runLoop) run];
dispatch_queue_t queue = dispatch_queue_create("com.videocore.network.sockets", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
[NSRL(m_runLoop) run];
});
#if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000
dispatch_release(queue);
#endif
}

}
}