SRRunLoopThread.m 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. //
  2. // Copyright 2012 Square Inc.
  3. // Portions Copyright (c) 2016-present, Facebook, Inc.
  4. //
  5. // All rights reserved.
  6. //
  7. // This source code is licensed under the BSD-style license found in the
  8. // LICENSE file in the root directory of this source tree. An additional grant
  9. // of patent rights can be found in the PATENTS file in the same directory.
  10. //
  11. #import "SRRunLoopThread.h"
  12. @interface SRRunLoopThread ()
  13. {
  14. dispatch_group_t _waitGroup;
  15. }
  16. @property (nonatomic, strong, readwrite) NSRunLoop *runLoop;
  17. @end
  18. @implementation SRRunLoopThread
  19. + (instancetype)sharedThread
  20. {
  21. static SRRunLoopThread *thread;
  22. static dispatch_once_t onceToken;
  23. dispatch_once(&onceToken, ^{
  24. thread = [[SRRunLoopThread alloc] init];
  25. thread.name = @"com.facebook.SocketRocket.NetworkThread";
  26. [thread start];
  27. });
  28. return thread;
  29. }
  30. - (instancetype)init
  31. {
  32. self = [super init];
  33. if (self) {
  34. _waitGroup = dispatch_group_create();
  35. dispatch_group_enter(_waitGroup);
  36. }
  37. return self;
  38. }
  39. - (void)main
  40. {
  41. @autoreleasepool {
  42. _runLoop = [NSRunLoop currentRunLoop];
  43. dispatch_group_leave(_waitGroup);
  44. // Add an empty run loop source to prevent runloop from spinning.
  45. CFRunLoopSourceContext sourceCtx = {
  46. .version = 0,
  47. .info = NULL,
  48. .retain = NULL,
  49. .release = NULL,
  50. .copyDescription = NULL,
  51. .equal = NULL,
  52. .hash = NULL,
  53. .schedule = NULL,
  54. .cancel = NULL,
  55. .perform = NULL
  56. };
  57. CFRunLoopSourceRef source = CFRunLoopSourceCreate(NULL, 0, &sourceCtx);
  58. CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
  59. CFRelease(source);
  60. while ([_runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]) {
  61. }
  62. assert(NO);
  63. }
  64. }
  65. - (NSRunLoop *)runLoop;
  66. {
  67. dispatch_group_wait(_waitGroup, DISPATCH_TIME_FOREVER);
  68. return _runLoop;
  69. }
  70. @end