SRRunLoopThread.m 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  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.qualityOfService = NSQualityOfServiceUserInitiated;
  27. [thread start];
  28. });
  29. return thread;
  30. }
  31. - (instancetype)init
  32. {
  33. self = [super init];
  34. if (self) {
  35. _waitGroup = dispatch_group_create();
  36. dispatch_group_enter(_waitGroup);
  37. }
  38. return self;
  39. }
  40. - (void)main
  41. {
  42. @autoreleasepool {
  43. _runLoop = [NSRunLoop currentRunLoop];
  44. dispatch_group_leave(_waitGroup);
  45. // Add an empty run loop source to prevent runloop from spinning.
  46. CFRunLoopSourceContext sourceCtx = {
  47. .version = 0,
  48. .info = NULL,
  49. .retain = NULL,
  50. .release = NULL,
  51. .copyDescription = NULL,
  52. .equal = NULL,
  53. .hash = NULL,
  54. .schedule = NULL,
  55. .cancel = NULL,
  56. .perform = NULL
  57. };
  58. CFRunLoopSourceRef source = CFRunLoopSourceCreate(NULL, 0, &sourceCtx);
  59. CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
  60. CFRelease(source);
  61. while ([_runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]) {
  62. }
  63. assert(NO);
  64. }
  65. }
  66. - (NSRunLoop *)runLoop
  67. {
  68. dispatch_group_wait(_waitGroup, DISPATCH_TIME_FOREVER);
  69. return _runLoop;
  70. }
  71. @end