passenger 5.0.25 → 5.0.26

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of passenger might be problematic. Click here for more details.

Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +20 -0
  3. data/CONTRIBUTORS +1 -0
  4. data/build/cxx_dependency_map.rb +7338 -7104
  5. data/build/cxx_tests.rb +3 -3
  6. data/build/misc.rb +1 -0
  7. data/dev/index_cxx_dependencies.rb +3 -2
  8. data/resources/templates/standalone/config.erb +1 -1
  9. data/resources/templates/standalone/http.erb +1 -0
  10. data/resources/templates/standalone/server.erb +1 -0
  11. data/src/agent/Core/ApplicationPool/AbstractSession.h +83 -0
  12. data/src/agent/Core/ApplicationPool/Common.h +6 -4
  13. data/src/agent/Core/ApplicationPool/Options.h +4 -1
  14. data/src/agent/Core/ApplicationPool/Pool.h +2 -2
  15. data/src/agent/Core/ApplicationPool/Pool/AnalyticsCollection.cpp +3 -6
  16. data/src/agent/Core/ApplicationPool/Pool/GeneralUtils.cpp +3 -3
  17. data/src/agent/Core/ApplicationPool/Session.h +15 -27
  18. data/src/agent/Core/ApplicationPool/TestSession.h +188 -0
  19. data/src/agent/Core/Controller.h +15 -6
  20. data/src/agent/Core/Controller/CheckoutSession.cpp +13 -5
  21. data/src/agent/Core/Controller/ForwardResponse.cpp +20 -2
  22. data/src/agent/Core/Controller/Hooks.cpp +15 -2
  23. data/src/agent/Core/Controller/InitRequest.cpp +5 -1
  24. data/src/agent/Core/Controller/InitializationAndShutdown.cpp +1 -0
  25. data/src/agent/Core/Controller/Request.h +11 -4
  26. data/src/agent/Core/Controller/SendRequest.cpp +34 -13
  27. data/src/agent/Core/Controller/StateInspectionAndConfiguration.cpp +2 -2
  28. data/src/agent/Core/CoreMain.cpp +27 -1
  29. data/src/agent/Core/OptionParser.h +11 -1
  30. data/src/agent/Core/SpawningKit/DirectSpawner.h +1 -0
  31. data/src/agent/Core/SpawningKit/SmartSpawner.h +1 -0
  32. data/src/agent/Core/SpawningKit/Spawner.h +21 -1
  33. data/src/agent/SpawnPreparer/SpawnPreparerMain.cpp +1 -1
  34. data/src/agent/UstRouter/OptionParser.h +7 -1
  35. data/src/agent/UstRouter/UstRouterMain.cpp +27 -1
  36. data/src/cxx_supportlib/Algorithms/MovingAverage.h +223 -0
  37. data/src/cxx_supportlib/Constants.h +2 -2
  38. data/src/cxx_supportlib/DataStructures/StringKeyTable.h +96 -40
  39. data/src/cxx_supportlib/ResourceLocator.h +33 -14
  40. data/src/cxx_supportlib/ServerKit/Channel.h +198 -69
  41. data/src/cxx_supportlib/ServerKit/Errors.h +6 -1
  42. data/src/cxx_supportlib/ServerKit/HttpRequest.h +20 -1
  43. data/src/cxx_supportlib/ServerKit/HttpServer.h +124 -32
  44. data/src/cxx_supportlib/ServerKit/Server.h +65 -1
  45. data/src/cxx_supportlib/Utils/IOUtils.cpp +12 -22
  46. data/src/cxx_supportlib/Utils/JsonUtils.h +87 -1
  47. data/src/cxx_supportlib/Utils/StrIntUtils.cpp +16 -1
  48. data/src/cxx_supportlib/Utils/StrIntUtils.h +31 -1
  49. data/src/cxx_supportlib/Utils/VariantMap.h +6 -1
  50. data/src/cxx_supportlib/WatchdogLauncher.h +17 -9
  51. data/src/cxx_supportlib/vendor-copy/libuv/AUTHORS +43 -0
  52. data/src/cxx_supportlib/vendor-copy/libuv/ChangeLog +350 -1
  53. data/src/cxx_supportlib/vendor-copy/libuv/Makefile.am +9 -1
  54. data/src/cxx_supportlib/vendor-copy/libuv/README.md +48 -0
  55. data/src/cxx_supportlib/vendor-copy/libuv/checksparse.sh +1 -0
  56. data/src/cxx_supportlib/vendor-copy/libuv/common.gypi +5 -5
  57. data/src/cxx_supportlib/vendor-copy/libuv/configure.ac +2 -1
  58. data/src/cxx_supportlib/vendor-copy/libuv/gyp_uv.py +0 -3
  59. data/src/cxx_supportlib/vendor-copy/libuv/include/uv-version.h +5 -1
  60. data/src/cxx_supportlib/vendor-copy/libuv/include/uv.h +30 -3
  61. data/src/cxx_supportlib/vendor-copy/libuv/src/fs-poll.c +3 -3
  62. data/src/cxx_supportlib/vendor-copy/libuv/src/inet.c +0 -4
  63. data/src/cxx_supportlib/vendor-copy/libuv/src/queue.h +17 -1
  64. data/src/cxx_supportlib/vendor-copy/libuv/src/threadpool.c +10 -10
  65. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/aix.c +84 -166
  66. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/android-ifaddrs.c +11 -11
  67. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/async.c +7 -1
  68. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/atomic-ops.h +17 -0
  69. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/core.c +140 -21
  70. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/darwin.c +15 -11
  71. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/dl.c +4 -7
  72. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/freebsd.c +52 -37
  73. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/fs.c +181 -60
  74. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/fsevents.c +39 -34
  75. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/getaddrinfo.c +4 -4
  76. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/internal.h +3 -1
  77. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/kqueue.c +12 -4
  78. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/linux-core.c +38 -15
  79. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/linux-inotify.c +36 -8
  80. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/linux-syscalls.c +4 -4
  81. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/linux-syscalls.h +2 -2
  82. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/loop-watcher.c +6 -1
  83. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/loop.c +28 -8
  84. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/netbsd.c +18 -16
  85. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/openbsd.c +18 -16
  86. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/pipe.c +3 -3
  87. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/process.c +18 -6
  88. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/proctitle.c +2 -2
  89. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/pthread-fixes.c +1 -0
  90. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/signal.c +2 -0
  91. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/stream.c +47 -30
  92. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/sunos.c +13 -11
  93. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/tcp.c +43 -8
  94. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/thread.c +21 -15
  95. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/tty.c +16 -2
  96. data/src/cxx_supportlib/vendor-copy/libuv/src/unix/udp.c +54 -14
  97. data/src/cxx_supportlib/vendor-copy/libuv/src/uv-common.c +104 -21
  98. data/src/cxx_supportlib/vendor-copy/libuv/src/uv-common.h +14 -1
  99. data/src/cxx_supportlib/vendor-copy/libuv/src/version.c +1 -5
  100. data/src/cxx_supportlib/vendor-copy/libuv/uv.gyp +22 -1
  101. data/src/nginx_module/CacheLocationConfig.c +52 -0
  102. data/src/nginx_module/CacheLocationConfig.c.erb +13 -1
  103. data/src/nginx_module/Configuration.c +1 -0
  104. data/src/nginx_module/Configuration.h +1 -0
  105. data/src/nginx_module/ConfigurationCommands.c +20 -0
  106. data/src/nginx_module/ConfigurationFields.h +4 -0
  107. data/src/nginx_module/CreateLocationConfig.c +8 -0
  108. data/src/nginx_module/MergeLocationConfig.c +12 -0
  109. data/src/nginx_module/config +31 -13
  110. data/src/nginx_module/ngx_http_passenger_module.c +4 -0
  111. data/src/ruby_supportlib/phusion_passenger.rb +1 -1
  112. data/src/ruby_supportlib/phusion_passenger/constants.rb +1 -1
  113. data/src/ruby_supportlib/phusion_passenger/nginx/config_options.rb +11 -1
  114. data/src/ruby_supportlib/phusion_passenger/platform_info/apache.rb +6 -1
  115. data/src/ruby_supportlib/phusion_passenger/rack/thread_handler_extension.rb +32 -31
  116. data/src/ruby_supportlib/phusion_passenger/standalone/config_options_list.rb +13 -2
  117. data/src/ruby_supportlib/phusion_passenger/standalone/config_utils.rb +1 -0
  118. data/src/ruby_supportlib/phusion_passenger/standalone/start_command/builtin_engine.rb +6 -1
  119. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core.rb +6 -0
  120. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/api.rb +29 -19
  121. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/context.rb +2 -2
  122. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/request_reporter.rb +2 -3
  123. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/simple_json.rb +2 -1
  124. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/spec_helper.rb +2 -0
  125. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/time_point.rb +3 -17
  126. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/transaction.rb +7 -10
  127. data/src/ruby_supportlib/phusion_passenger/vendor/union_station_hooks_core/lib/union_station_hooks_core/utils.rb +11 -9
  128. metadata +5 -2
@@ -73,9 +73,16 @@ typedef struct uv__fsevents_event_s uv__fsevents_event_t;
73
73
  typedef struct uv__cf_loop_signal_s uv__cf_loop_signal_t;
74
74
  typedef struct uv__cf_loop_state_s uv__cf_loop_state_t;
75
75
 
76
+ enum uv__cf_loop_signal_type_e {
77
+ kUVCFLoopSignalRegular,
78
+ kUVCFLoopSignalClosing
79
+ };
80
+ typedef enum uv__cf_loop_signal_type_e uv__cf_loop_signal_type_t;
81
+
76
82
  struct uv__cf_loop_signal_s {
77
83
  QUEUE member;
78
84
  uv_fs_event_t* handle;
85
+ uv__cf_loop_signal_type_t type;
79
86
  };
80
87
 
81
88
  struct uv__fsevents_event_s {
@@ -98,7 +105,9 @@ struct uv__cf_loop_state_s {
98
105
  /* Forward declarations */
99
106
  static void uv__cf_loop_cb(void* arg);
100
107
  static void* uv__cf_loop_runner(void* arg);
101
- static int uv__cf_loop_signal(uv_loop_t* loop, uv_fs_event_t* handle);
108
+ static int uv__cf_loop_signal(uv_loop_t* loop,
109
+ uv_fs_event_t* handle,
110
+ uv__cf_loop_signal_type_t type);
102
111
 
103
112
  /* Lazy-loaded by uv__fsevents_global_init(). */
104
113
  static CFArrayRef (*pCFArrayCreate)(CFAllocatorRef,
@@ -149,11 +158,7 @@ static void (*pFSEventStreamStop)(FSEventStreamRef);
149
158
  int err; \
150
159
  uv_mutex_lock(&(handle)->cf_mutex); \
151
160
  /* Split-off all events and empty original queue */ \
152
- QUEUE_INIT(&events); \
153
- if (!QUEUE_EMPTY(&(handle)->cf_events)) { \
154
- q = QUEUE_HEAD(&(handle)->cf_events); \
155
- QUEUE_SPLIT(&(handle)->cf_events, q, &events); \
156
- } \
161
+ QUEUE_MOVE(&(handle)->cf_events, &events); \
157
162
  /* Get error (if any) and zero original one */ \
158
163
  err = (handle)->cf_error; \
159
164
  (handle)->cf_error = 0; \
@@ -169,7 +174,7 @@ static void (*pFSEventStreamStop)(FSEventStreamRef);
169
174
  if (!uv__is_closing((handle)) && uv__is_active((handle))) \
170
175
  block \
171
176
  /* Free allocated data */ \
172
- free(event); \
177
+ uv__free(event); \
173
178
  } \
174
179
  if (err != 0 && !uv__is_closing((handle)) && uv__is_active((handle))) \
175
180
  (handle)->cb((handle), NULL, 0, err); \
@@ -280,7 +285,7 @@ static void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
280
285
  len = 0;
281
286
  #endif /* MAC_OS_X_VERSION_10_7 */
282
287
 
283
- event = malloc(sizeof(*event) + len);
288
+ event = uv__malloc(sizeof(*event) + len);
284
289
  if (event == NULL)
285
290
  break;
286
291
 
@@ -387,7 +392,8 @@ static void uv__fsevents_destroy_stream(uv_loop_t* loop) {
387
392
 
388
393
 
389
394
  /* Runs in CF thread, when there're new fsevent handles to add to stream */
390
- static void uv__fsevents_reschedule(uv_fs_event_t* handle) {
395
+ static void uv__fsevents_reschedule(uv_fs_event_t* handle,
396
+ uv__cf_loop_signal_type_t type) {
391
397
  uv__cf_loop_state_t* state;
392
398
  QUEUE* q;
393
399
  uv_fs_event_t* curr;
@@ -425,7 +431,7 @@ static void uv__fsevents_reschedule(uv_fs_event_t* handle) {
425
431
  uv_mutex_lock(&state->fsevent_mutex);
426
432
  path_count = state->fsevent_handle_count;
427
433
  if (path_count != 0) {
428
- paths = malloc(sizeof(*paths) * path_count);
434
+ paths = uv__malloc(sizeof(*paths) * path_count);
429
435
  if (paths == NULL) {
430
436
  uv_mutex_unlock(&state->fsevent_mutex);
431
437
  goto final;
@@ -465,7 +471,7 @@ final:
465
471
  if (cf_paths == NULL) {
466
472
  while (i != 0)
467
473
  pCFRelease(paths[--i]);
468
- free(paths);
474
+ uv__free(paths);
469
475
  } else {
470
476
  /* CFArray takes ownership of both strings and original C-array */
471
477
  pCFRelease(cf_paths);
@@ -486,7 +492,7 @@ final:
486
492
  *
487
493
  * NOTE: This is coupled with `uv_sem_wait()` in `uv__fsevents_close`
488
494
  */
489
- if (!uv__is_active(handle))
495
+ if (type == kUVCFLoopSignalClosing)
490
496
  uv_sem_post(&state->fsevent_sem);
491
497
  }
492
498
 
@@ -584,7 +590,7 @@ static int uv__fsevents_loop_init(uv_loop_t* loop) {
584
590
  if (err)
585
591
  return err;
586
592
 
587
- state = calloc(1, sizeof(*state));
593
+ state = uv__calloc(1, sizeof(*state));
588
594
  if (state == NULL)
589
595
  return -ENOMEM;
590
596
 
@@ -662,7 +668,7 @@ fail_sem_init:
662
668
  uv_mutex_destroy(&loop->cf_mutex);
663
669
 
664
670
  fail_mutex_init:
665
- free(state);
671
+ uv__free(state);
666
672
  return err;
667
673
  }
668
674
 
@@ -676,7 +682,7 @@ void uv__fsevents_loop_delete(uv_loop_t* loop) {
676
682
  if (loop->cf_state == NULL)
677
683
  return;
678
684
 
679
- if (uv__cf_loop_signal(loop, NULL) != 0)
685
+ if (uv__cf_loop_signal(loop, NULL, kUVCFLoopSignalRegular) != 0)
680
686
  abort();
681
687
 
682
688
  uv_thread_join(&loop->cf_thread);
@@ -688,7 +694,7 @@ void uv__fsevents_loop_delete(uv_loop_t* loop) {
688
694
  q = QUEUE_HEAD(&loop->cf_signals);
689
695
  s = QUEUE_DATA(q, uv__cf_loop_signal_t, member);
690
696
  QUEUE_REMOVE(q);
691
- free(s);
697
+ uv__free(s);
692
698
  }
693
699
 
694
700
  /* Destroy state */
@@ -696,7 +702,7 @@ void uv__fsevents_loop_delete(uv_loop_t* loop) {
696
702
  uv_sem_destroy(&state->fsevent_sem);
697
703
  uv_mutex_destroy(&state->fsevent_mutex);
698
704
  pCFRelease(state->signal_source);
699
- free(state);
705
+ uv__free(state);
700
706
  loop->cf_state = NULL;
701
707
  }
702
708
 
@@ -735,17 +741,14 @@ static void uv__cf_loop_cb(void* arg) {
735
741
 
736
742
  loop = arg;
737
743
  state = loop->cf_state;
738
- QUEUE_INIT(&split_head);
739
744
 
740
745
  uv_mutex_lock(&loop->cf_mutex);
741
- if (!QUEUE_EMPTY(&loop->cf_signals)) {
742
- QUEUE* split_pos = QUEUE_HEAD(&loop->cf_signals);
743
- QUEUE_SPLIT(&loop->cf_signals, split_pos, &split_head);
744
- }
746
+ QUEUE_MOVE(&loop->cf_signals, &split_head);
745
747
  uv_mutex_unlock(&loop->cf_mutex);
746
748
 
747
749
  while (!QUEUE_EMPTY(&split_head)) {
748
750
  item = QUEUE_HEAD(&split_head);
751
+ QUEUE_REMOVE(item);
749
752
 
750
753
  s = QUEUE_DATA(item, uv__cf_loop_signal_t, member);
751
754
 
@@ -753,24 +756,26 @@ static void uv__cf_loop_cb(void* arg) {
753
756
  if (s->handle == NULL)
754
757
  pCFRunLoopStop(state->loop);
755
758
  else
756
- uv__fsevents_reschedule(s->handle);
759
+ uv__fsevents_reschedule(s->handle, s->type);
757
760
 
758
- QUEUE_REMOVE(item);
759
- free(s);
761
+ uv__free(s);
760
762
  }
761
763
  }
762
764
 
763
765
 
764
766
  /* Runs in UV loop to notify CF thread */
765
- int uv__cf_loop_signal(uv_loop_t* loop, uv_fs_event_t* handle) {
767
+ int uv__cf_loop_signal(uv_loop_t* loop,
768
+ uv_fs_event_t* handle,
769
+ uv__cf_loop_signal_type_t type) {
766
770
  uv__cf_loop_signal_t* item;
767
771
  uv__cf_loop_state_t* state;
768
772
 
769
- item = malloc(sizeof(*item));
773
+ item = uv__malloc(sizeof(*item));
770
774
  if (item == NULL)
771
775
  return -ENOMEM;
772
776
 
773
777
  item->handle = handle;
778
+ item->type = type;
774
779
 
775
780
  uv_mutex_lock(&loop->cf_mutex);
776
781
  QUEUE_INSERT_TAIL(&loop->cf_signals, &item->member);
@@ -808,7 +813,7 @@ int uv__fsevents_init(uv_fs_event_t* handle) {
808
813
  * Events will occur in other thread.
809
814
  * Initialize callback for getting them back into event loop's thread
810
815
  */
811
- handle->cf_cb = malloc(sizeof(*handle->cf_cb));
816
+ handle->cf_cb = uv__malloc(sizeof(*handle->cf_cb));
812
817
  if (handle->cf_cb == NULL) {
813
818
  err = -ENOMEM;
814
819
  goto fail_cf_cb_malloc;
@@ -833,7 +838,7 @@ int uv__fsevents_init(uv_fs_event_t* handle) {
833
838
 
834
839
  /* Reschedule FSEventStream */
835
840
  assert(handle != NULL);
836
- err = uv__cf_loop_signal(handle->loop, handle);
841
+ err = uv__cf_loop_signal(handle->loop, handle, kUVCFLoopSignalRegular);
837
842
  if (err)
838
843
  goto fail_loop_signal;
839
844
 
@@ -843,11 +848,11 @@ fail_loop_signal:
843
848
  uv_mutex_destroy(&handle->cf_mutex);
844
849
 
845
850
  fail_cf_mutex_init:
846
- free(handle->cf_cb);
851
+ uv__free(handle->cf_cb);
847
852
  handle->cf_cb = NULL;
848
853
 
849
854
  fail_cf_cb_malloc:
850
- free(handle->realpath);
855
+ uv__free(handle->realpath);
851
856
  handle->realpath = NULL;
852
857
  handle->realpath_len = 0;
853
858
 
@@ -873,14 +878,14 @@ int uv__fsevents_close(uv_fs_event_t* handle) {
873
878
 
874
879
  /* Reschedule FSEventStream */
875
880
  assert(handle != NULL);
876
- err = uv__cf_loop_signal(handle->loop, handle);
881
+ err = uv__cf_loop_signal(handle->loop, handle, kUVCFLoopSignalClosing);
877
882
  if (err)
878
883
  return -err;
879
884
 
880
885
  /* Wait for deinitialization */
881
886
  uv_sem_wait(&state->fsevent_sem);
882
887
 
883
- uv_close((uv_handle_t*) handle->cf_cb, (uv_close_cb) free);
888
+ uv_close((uv_handle_t*) handle->cf_cb, (uv_close_cb) uv__free);
884
889
  handle->cf_cb = NULL;
885
890
 
886
891
  /* Free data in queue */
@@ -889,7 +894,7 @@ int uv__fsevents_close(uv_fs_event_t* handle) {
889
894
  });
890
895
 
891
896
  uv_mutex_destroy(&handle->cf_mutex);
892
- free(handle->realpath);
897
+ uv__free(handle->realpath);
893
898
  handle->realpath = NULL;
894
899
  handle->realpath_len = 0;
895
900
 
@@ -112,11 +112,11 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) {
112
112
 
113
113
  /* See initialization in uv_getaddrinfo(). */
114
114
  if (req->hints)
115
- free(req->hints);
115
+ uv__free(req->hints);
116
116
  else if (req->service)
117
- free(req->service);
117
+ uv__free(req->service);
118
118
  else if (req->hostname)
119
- free(req->hostname);
119
+ uv__free(req->hostname);
120
120
  else
121
121
  assert(0);
122
122
 
@@ -152,7 +152,7 @@ int uv_getaddrinfo(uv_loop_t* loop,
152
152
  hostname_len = hostname ? strlen(hostname) + 1 : 0;
153
153
  service_len = service ? strlen(service) + 1 : 0;
154
154
  hints_len = hints ? sizeof(*hints) : 0;
155
- buf = malloc(hostname_len + service_len + hints_len);
155
+ buf = uv__malloc(hostname_len + service_len + hints_len);
156
156
 
157
157
  if (buf == NULL)
158
158
  return -ENOMEM;
@@ -143,7 +143,8 @@ enum {
143
143
  UV_TCP_NODELAY = 0x400, /* Disable Nagle. */
144
144
  UV_TCP_KEEPALIVE = 0x800, /* Turn on keep-alive. */
145
145
  UV_TCP_SINGLE_ACCEPT = 0x1000, /* Only accept() when idle. */
146
- UV_HANDLE_IPV6 = 0x10000 /* Handle is bound to a IPv6 socket. */
146
+ UV_HANDLE_IPV6 = 0x10000, /* Handle is bound to a IPv6 socket. */
147
+ UV_UDP_PROCESSING = 0x20000 /* Handle is running the send callback queue. */
147
148
  };
148
149
 
149
150
  /* loop flags */
@@ -171,6 +172,7 @@ int uv__socket(int domain, int type, int protocol);
171
172
  int uv__dup(int fd);
172
173
  ssize_t uv__recvmsg(int fd, struct msghdr *msg, int flags);
173
174
  void uv__make_close_pending(uv_handle_t* handle);
175
+ int uv__getiovmax(void);
174
176
 
175
177
  void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd);
176
178
  void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events);
@@ -363,7 +363,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
363
363
 
364
364
  uv__handle_start(handle);
365
365
  uv__io_init(&handle->event_watcher, uv__fs_event, fd);
366
- handle->path = strdup(path);
366
+ handle->path = uv__strdup(path);
367
367
  handle->cb = cb;
368
368
 
369
369
  #if defined(__APPLE__)
@@ -379,6 +379,10 @@ int uv_fs_event_start(uv_fs_event_t* handle,
379
379
  if (!(statbuf.st_mode & S_IFDIR))
380
380
  goto fallback;
381
381
 
382
+ /* The fallback fd is no longer needed */
383
+ uv__close(fd);
384
+ handle->event_watcher.fd = -1;
385
+
382
386
  return uv__fsevents_init(handle);
383
387
 
384
388
  fallback:
@@ -403,11 +407,15 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
403
407
  uv__io_close(handle->loop, &handle->event_watcher);
404
408
  }
405
409
 
406
- free(handle->path);
410
+ uv__free(handle->path);
407
411
  handle->path = NULL;
408
412
 
409
- uv__close(handle->event_watcher.fd);
410
- handle->event_watcher.fd = -1;
413
+ if (handle->event_watcher.fd != -1) {
414
+ /* When FSEvents is used, we don't use the event_watcher's fd under certain
415
+ * confitions. (see uv_fs_event_start) */
416
+ uv__close(handle->event_watcher.fd);
417
+ handle->event_watcher.fd = -1;
418
+ }
411
419
 
412
420
  return 0;
413
421
  }
@@ -141,17 +141,26 @@ void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
141
141
 
142
142
 
143
143
  void uv__io_poll(uv_loop_t* loop, int timeout) {
144
+ /* A bug in kernels < 2.6.37 makes timeouts larger than ~30 minutes
145
+ * effectively infinite on 32 bits architectures. To avoid blocking
146
+ * indefinitely, we cap the timeout and poll again if necessary.
147
+ *
148
+ * Note that "30 minutes" is a simplification because it depends on
149
+ * the value of CONFIG_HZ. The magic constant assumes CONFIG_HZ=1200,
150
+ * that being the largest value I have seen in the wild (and only once.)
151
+ */
152
+ static const int max_safe_timeout = 1789569;
144
153
  static int no_epoll_pwait;
145
154
  static int no_epoll_wait;
146
155
  struct uv__epoll_event events[1024];
147
156
  struct uv__epoll_event* pe;
148
157
  struct uv__epoll_event e;
158
+ int real_timeout;
149
159
  QUEUE* q;
150
160
  uv__io_t* w;
151
161
  sigset_t sigset;
152
162
  uint64_t sigmask;
153
163
  uint64_t base;
154
- uint64_t diff;
155
164
  int nevents;
156
165
  int count;
157
166
  int nfds;
@@ -209,8 +218,15 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
209
218
  assert(timeout >= -1);
210
219
  base = loop->time;
211
220
  count = 48; /* Benchmarks suggest this gives the best throughput. */
221
+ real_timeout = timeout;
212
222
 
213
223
  for (;;) {
224
+ /* See the comment for max_safe_timeout for an explanation of why
225
+ * this is necessary. Executive summary: kernel bug workaround.
226
+ */
227
+ if (sizeof(int32_t) == sizeof(long) && timeout >= max_safe_timeout)
228
+ timeout = max_safe_timeout;
229
+
214
230
  if (sigmask != 0 && no_epoll_pwait != 0)
215
231
  if (pthread_sigmask(SIG_BLOCK, &sigset, NULL))
216
232
  abort();
@@ -244,6 +260,11 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
244
260
 
245
261
  if (nfds == 0) {
246
262
  assert(timeout != -1);
263
+
264
+ timeout = real_timeout - timeout;
265
+ if (timeout > 0)
266
+ continue;
267
+
247
268
  return;
248
269
  }
249
270
 
@@ -346,11 +367,11 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
346
367
  update_timeout:
347
368
  assert(timeout > 0);
348
369
 
349
- diff = loop->time - base;
350
- if (diff >= (uint64_t) timeout)
370
+ real_timeout -= (loop->time - base);
371
+ if (real_timeout <= 0)
351
372
  return;
352
373
 
353
- timeout -= diff;
374
+ timeout = real_timeout;
354
375
  }
355
376
  }
356
377
 
@@ -523,7 +544,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
523
544
  assert(numcpus != (unsigned int) -1);
524
545
  assert(numcpus != 0);
525
546
 
526
- ci = calloc(numcpus, sizeof(*ci));
547
+ ci = uv__calloc(numcpus, sizeof(*ci));
527
548
  if (ci == NULL)
528
549
  return -ENOMEM;
529
550
 
@@ -595,7 +616,7 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
595
616
  if (model_idx < numcpus) {
596
617
  if (strncmp(buf, model_marker, sizeof(model_marker) - 1) == 0) {
597
618
  model = buf + sizeof(model_marker) - 1;
598
- model = strndup(model, strlen(model) - 1); /* Strip newline. */
619
+ model = uv__strndup(model, strlen(model) - 1); /* Strip newline. */
599
620
  if (model == NULL) {
600
621
  fclose(fp);
601
622
  return -ENOMEM;
@@ -614,7 +635,7 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
614
635
  #endif
615
636
  if (strncmp(buf, model_marker, sizeof(model_marker) - 1) == 0) {
616
637
  model = buf + sizeof(model_marker) - 1;
617
- model = strndup(model, strlen(model) - 1); /* Strip newline. */
638
+ model = uv__strndup(model, strlen(model) - 1); /* Strip newline. */
618
639
  if (model == NULL) {
619
640
  fclose(fp);
620
641
  return -ENOMEM;
@@ -645,7 +666,7 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
645
666
  inferred_model = ci[model_idx - 1].model;
646
667
 
647
668
  while (model_idx < numcpus) {
648
- model = strndup(inferred_model, strlen(inferred_model));
669
+ model = uv__strndup(inferred_model, strlen(inferred_model));
649
670
  if (model == NULL)
650
671
  return -ENOMEM;
651
672
  ci[model_idx++].model = model;
@@ -755,10 +776,10 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
755
776
  int i;
756
777
 
757
778
  for (i = 0; i < count; i++) {
758
- free(cpu_infos[i].model);
779
+ uv__free(cpu_infos[i].model);
759
780
  }
760
781
 
761
- free(cpu_infos);
782
+ uv__free(cpu_infos);
762
783
  }
763
784
 
764
785
 
@@ -792,9 +813,11 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
792
813
  if (*count == 0)
793
814
  return 0;
794
815
 
795
- *addresses = malloc(*count * sizeof(**addresses));
796
- if (!(*addresses))
816
+ *addresses = uv__malloc(*count * sizeof(**addresses));
817
+ if (!(*addresses)) {
818
+ freeifaddrs(addrs);
797
819
  return -ENOMEM;
820
+ }
798
821
 
799
822
  address = *addresses;
800
823
 
@@ -812,7 +835,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
812
835
  if (ent->ifa_addr->sa_family == PF_PACKET)
813
836
  continue;
814
837
 
815
- address->name = strdup(ent->ifa_name);
838
+ address->name = uv__strdup(ent->ifa_name);
816
839
 
817
840
  if (ent->ifa_addr->sa_family == AF_INET6) {
818
841
  address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
@@ -862,10 +885,10 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses,
862
885
  int i;
863
886
 
864
887
  for (i = 0; i < count; i++) {
865
- free(addresses[i].name);
888
+ uv__free(addresses[i].name);
866
889
  }
867
890
 
868
- free(addresses);
891
+ uv__free(addresses);
869
892
  }
870
893
 
871
894