-
Notifications
You must be signed in to change notification settings - Fork 583
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[READY] hs.socket #791
[READY] hs.socket #791
Conversation
|
||
static const char *USERDATA_TAG = "hs.socket"; | ||
|
||
int refTable; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(This isn't documented anywhere yet, or even widespread convention, but) this should be static too
return [super initWithDelegate:self delegateQueue:dispatch_get_main_queue()]; | ||
} | ||
|
||
- (void)socket:(HSAsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this guaranteed to be called on the main thread by GCDASyncSocket? I am guessing it must be, otherwise you would have had failures from LuaSkin when it noticed it was being accessed from a non-main thread, but it seems like everything else here is expecting to be happening on random threads.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. You can specify your own background serial queue like:
- (id)init {
dispatch_queue_t socketQueue = dispatch_queue_create("socketQueue", NULL);
...
return [super initWithDelegate:self delegateQueue:socketQueue];
}
Then, in each of the delegate methods that operate on the UI/Lua in any way, you must wrap those operations like so:
dispatch_async(dispatch_get_main_queue(), ^{
@autoreleasepool {
LuaSkin *skin = [LuaSkin shared];
[skin logInfo:@"Data written to socket"];
// do some lua callback or something
}
});
Failing to dispatch_async
to the main thread will indeed crash as you say. I initially chose dispatch_get_main_queue
as the delegateQueue
because it 'just worked', but it does seem a bit more performant if I use background queues and call dispatch_async
to the main thread as shown above, presumably because GCDAsyncSocket avoids doing all of its internal operations on the main thread, waiting until the results are in. I have an uncommitted implementation of this and wanted your opinion before really putting it in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How feasible/difficult would it be to have LuaSkin's log* methods automatically call dispatch_async
to the main thread for log operations performed on background threads, with everything else being subjected to the if (![NSThread isMainThread])
check performed in + (id)shared
? Seems to me like that wouldn't be terribly unsafe, but might be too much work for not a lot of benefit.
In any case I've converted it to use the background queue with dispatch_async
to the main thread where needed and it passes all tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The most reliable way to do this is to add class methods for the logX: methods... anything that relies on [LuaSkin shared] will be rejected before the method is ever entered. (e.g. [LuaSkin logWarn:...]
rather than/in addition to [[LuaSkin shared] logWarn:...]
It's not a bad idea, maybe even include a prefix indicating when it's from another thread; @cmsj objections to my adding this? I'd also like to see hs.logger
used in the Lua side of the output so verbose and debug can be turned on and off as desired and can add that at the same time.
@heptal this is looking really good. I commented with a few little bits and bobs, but on the whole I am super pleased with this PR! Thanks very much :) |
a8a9e1f
to
1c57aa8
Compare
I think this is ready. It exposes pretty much everything in CocoaAsyncSocket.
|
…serdata_gc, change registerLibraryWithObject to separate registerLibrary/registerObject
…re similarly to hs.socket
Adds
hs.socket
for communicating with arbitrary protocols usingCocoaAsyncSocket
.TCP sockets are available under
hs.socket
UDP sockets are available under
hs.socket.udp