FreeSWITCH API Documentation  1.7.0
switch_time.c
Go to the documentation of this file.
1 /*
2  * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3  * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4  *
5  * Version: MPL 1.1
6  *
7  * The contents of this file are subject to the Mozilla Public License Version
8  * 1.1 (the "License"); you may not use this file except in compliance with
9  * the License. You may obtain a copy of the License at
10  * http://www.mozilla.org/MPL/
11  *
12  * Software distributed under the License is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14  * for the specific language governing rights and limitations under the
15  * License.
16  *
17  * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18  *
19  * The Initial Developer of the Original Code is
20  * Anthony Minessale II <anthm@freeswitch.org>
21  * Portions created by the Initial Developer are Copyright (C)
22  * the Initial Developer. All Rights Reserved.
23  *
24  * Contributor(s):
25  *
26  * Anthony Minessale II <anthm@freeswitch.org>
27  * Massimo Cetra <devel@navynet.it> - Timezone functionality
28  *
29  *
30  * softtimer.c -- Software Timer Module
31  *
32  */
33 
34 #include <switch.h>
35 #include <stdio.h>
37 
38 #ifdef HAVE_TIMERFD_CREATE
39 #include <sys/timerfd.h>
40 #endif
41 
42 //#if defined(DARWIN)
43 #define DISABLE_1MS_COND
44 //#endif
45 
46 #ifndef UINT32_MAX
47 #define UINT32_MAX 0xffffffff
48 #endif
49 
50 #define MAX_TICK UINT32_MAX - 1024
51 
52 #define MAX_ELEMENTS 3600
53 #define IDLE_SPEED 100
54 
55 /* In Windows, enable the montonic timer for better timer accuracy,
56  * GetSystemTimeAsFileTime does not update on timeBeginPeriod on these OS.
57  * Flag SCF_USE_WIN32_MONOTONIC must be enabled to activate it (start parameter -monotonic-clock).
58  */
59 
60 #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
61 static int MONO = 1;
62 #else
63 static int MONO = 0;
64 #endif
65 
66 
67 static int SYSTEM_TIME = 0;
68 
69 /* clock_nanosleep works badly on some kernels but really well on others.
70  timerfd seems to work well as long as it exists so if you have timerfd we'll also enable clock_nanosleep by default.
71 */
72 #if defined(HAVE_TIMERFD_CREATE)
73 static int TFD = 2;
74 #if defined(HAVE_CLOCK_NANOSLEEP)
75 static int NANO = 1;
76 #else
77 static int NANO = 0;
78 #endif
79 #else
80 static int TFD = 0;
81 static int NANO = 0;
82 #endif
83 
84 static int OFFSET = 0;
85 
86 static int COND = 1;
87 
88 static int MATRIX = 1;
89 
90 #ifdef WIN32
91 static CRITICAL_SECTION timer_section;
92 static switch_time_t win32_tick_time_since_start = -1;
93 static DWORD win32_last_get_time_tick = 0;
94 
95 static uint8_t win32_use_qpc = 0;
96 static uint64_t win32_qpc_freq = 0;
97 #endif
98 
100 
101 static struct {
102  int32_t RUNNING;
103  int32_t STARTED;
104  int32_t use_cond_yield;
106  uint32_t timer_count;
107 } globals;
108 
109 #ifdef WIN32
110 #undef SWITCH_MOD_DECLARE_DATA
111 #define SWITCH_MOD_DECLARE_DATA __declspec(dllexport)
112 #endif
113 
114 SWITCH_MODULE_LOAD_FUNCTION(softtimer_load);
115 SWITCH_MODULE_SHUTDOWN_FUNCTION(softtimer_shutdown);
116 SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime);
117 SWITCH_MODULE_DEFINITION(CORE_SOFTTIMER_MODULE, softtimer_load, softtimer_shutdown, softtimer_runtime);
118 
122  uint32_t roll;
123  uint32_t ready;
124 };
126 
127 struct timer_matrix {
128  uint64_t tick;
129  uint32_t count;
130  uint32_t roll;
134 };
136 
138 
139 static switch_time_t time_now(int64_t offset);
140 
142 {
143 #if defined(WIN32)
144  SwitchToThread();
145 #else
146  sched_yield();
147 #endif
148 }
149 
151 {
152 #if defined(HAVE_CLOCK_NANOSLEEP) || defined(DARWIN)
153  struct timespec ts;
154 #endif
155 
156 #if defined(WIN32)
157  if (t < 1000) {
158  t = 1000;
159  }
160 #endif
161 
162 #if !defined(DARWIN)
163  if (t > 100000 || !NANO) {
164  apr_sleep(t);
165  return;
166  }
167 #endif
168 
169 #if defined(HAVE_CLOCK_NANOSLEEP)
170  t -= OFFSET;
171  ts.tv_sec = t / 1000000;
172  ts.tv_nsec = ((t % 1000000) * 1000);
173  clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
174 
175 #elif defined(DARWIN)
176  t -= OFFSET;
177  ts.tv_sec = t / APR_USEC_PER_SEC;
178  ts.tv_nsec = (t % APR_USEC_PER_SEC) * 850;
179  nanosleep(&ts, NULL);
180 #else
181  apr_sleep(t);
182 #endif
183 
184 #if defined(DARWIN)
185  sched_yield();
186 #endif
187 
188 }
189 
191 {
192  int x = 0;
193  switch_time_t start, stop, sum = 0;
194 
195  for (x = 0; x < reps; x++) {
196  start = switch_time_ref();
197  do_sleep(t);
198  stop = switch_time_ref();
199  sum += (stop - start);
200  }
201 
202  return sum / reps;
203 
204 }
205 
206 #define calc_step() if (step > 11) step -= 10; else if (step > 1) step--
208 {
209  int x;
210  switch_interval_time_t avg, val = 1000, want = 1000;
211  int over = 0, under = 0, good = 0, step = 50, diff = 0, retry = 0, lastgood = 0, one_k = 0;
212 
213 #ifdef HAVE_CLOCK_GETRES
214  struct timespec ts;
215  long res = 0;
216  clock_getres(CLOCK_MONOTONIC, &ts);
217  res = ts.tv_nsec / 1000;
218 
219 
220  if (res > 900 && res < 1100) {
221  one_k = 1;
222  }
223 
224  if (res > 1500) {
226  "Timer resolution of %ld microseconds detected!\n"
227  "Do you have your kernel timer frequency set to lower than 1,000Hz? "
228  "You may experience audio problems. Step MS %d\n", ts.tv_nsec / 1000, runtime.microseconds_per_tick / 1000);
229  do_sleep(5000000);
231  return;
232  }
233 #endif
234 
235  top:
236  val = 1000;
237  step = 50;
238  over = under = good = 0;
239  OFFSET = 0;
240 
241  for (x = 0; x < 100; x++) {
242  avg = average_time(val, 50);
243  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Test: %ld Average: %ld Step: %d\n", (long) val, (long) avg, step);
244 
245  diff = abs((int) (want - avg));
246  if (diff > 1500) {
248  "Abnormally large timer gap %d detected!\n"
249  "Do you have your kernel timer frequency set to lower than 1,000Hz? You may experience audio problems.\n", diff);
250  do_sleep(5000000);
252  return;
253  }
254 
255  if (diff <= 100) {
256  lastgood = (int) val;
257  }
258 
259  if (diff <= 2) {
260  under = over = 0;
261  lastgood = (int) val;
262  if (++good > 10) {
263  break;
264  }
265  } else if (avg > want) {
266  if (under) {
267  calc_step();
268  }
269  under = good = 0;
270  if ((val - step) < 0) {
271  if (++retry > 2)
272  break;
273  goto top;
274  }
275  val -= step;
276  over++;
277  } else if (avg < want) {
278  if (over) {
279  calc_step();
280  }
281  over = good = 0;
282  if ((val - step) < 0) {
283  if (++retry > 2)
284  break;
285  goto top;
286  }
287  val += step;
288  under++;
289  }
290  }
291 
292  if (good >= 10) {
293  OFFSET = (int) (want - val);
294  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Timer offset of %d calculated\n", OFFSET);
295  } else if (lastgood) {
296  OFFSET = (int) (want - lastgood);
297  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Timer offset of %d calculated (fallback)\n", OFFSET);
299  } else if (one_k) {
300  OFFSET = 900;
301  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Timer offset CANNOT BE DETECTED, forcing OFFSET to 900\n");
303  } else {
304  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Timer offset NOT calculated\n");
306  }
307 }
308 
309 
311 {
312  return (globals.RUNNING == 1 && runtime.timestamp) ? runtime.timestamp : switch_time_now();
313 }
314 
316 {
317  return time_now(-1);
318 }
319 
320 
322 {
323  time_t now = switch_micro_time_now() / APR_USEC_PER_SEC;
324  if (t) {
325  *t = now;
326  }
327  return now;
328 }
329 
331 {
332 #if (defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)) || defined(WIN32)
333  MONO = enable ? 1 : 0;
335 #else
336  MONO = 0;
337 #endif
338 }
339 
340 
342 {
343  SYSTEM_TIME = enable;
344 }
345 
346 
348 {
349 #if defined(HAVE_TIMERFD_CREATE)
350  TFD = enable;
352 
353 #else
354  TFD = 0;
355 #endif
356 }
357 
358 
360 {
361  MATRIX = enable ? 1 : 0;
363 }
364 
366 {
367 #if defined(HAVE_CLOCK_NANOSLEEP)
368  NANO = enable ? 1 : 0;
369 #endif
370 }
371 
373 {
374  COND = enable ? 1 : 0;
375  if (COND) {
376  MATRIX = 1;
377  }
379 }
380 
382 {
384  int64_t elapsed = (now - timer->start);
385 
386  timer->tick = (elapsed / timer->interval) / 1000;
387  timer->samplecount = (uint32_t)(timer->tick * timer->samples);
388 
389  return SWITCH_STATUS_SUCCESS;
390 }
391 
392 
393 
394 /////////
395 #ifdef HAVE_TIMERFD_CREATE
396 
397 #define MAX_INTERVAL 2000 /* ms */
398 
399 struct interval_timer {
400  int fd;
401 };
402 typedef struct interval_timer interval_timer_t;
403 
404 static switch_status_t timerfd_start_interval(interval_timer_t *it, int interval)
405 {
406  struct itimerspec val;
407  int fd, r;
408  uint64_t exp;
409 
410  fd = timerfd_create(CLOCK_MONOTONIC, 0);
411 
412  if (fd < 0) {
413  return SWITCH_STATUS_GENERR;
414  }
415 
416  val.it_interval.tv_sec = interval / 1000;
417  val.it_interval.tv_nsec = (interval % 1000) * 1000000;
418  val.it_value.tv_sec = 0;
419  val.it_value.tv_nsec = 100000;
420 
421  if (timerfd_settime(fd, 0, &val, NULL) < 0) {
422  close(fd);
423  return SWITCH_STATUS_GENERR;
424  }
425 
426  if ((r = read(fd, &exp, sizeof(exp)) < 0)) {
427  close(fd);
428  return SWITCH_STATUS_GENERR;
429  }
430 
431  it->fd = fd;
432 
433  return SWITCH_STATUS_SUCCESS;
434 }
435 
436 static switch_status_t timerfd_stop_interval(interval_timer_t *it)
437 {
438  close(it->fd);
439  it->fd = -1;
440  return SWITCH_STATUS_SUCCESS;
441 }
442 
443 static switch_status_t _timerfd_init(switch_timer_t *timer)
444 {
445  interval_timer_t *it;
446  int rc;
447 
448  if (timer->interval < 1 || timer->interval > MAX_INTERVAL)
449  return SWITCH_STATUS_GENERR;
450 
451  it = switch_core_alloc(timer->memory_pool, sizeof(*it));
452 
453  if ((rc = timerfd_start_interval(it, timer->interval)) == SWITCH_STATUS_SUCCESS) {
454  timer->start = switch_micro_time_now();
455  timer->private_info = it;
456  }
457 
458  return rc;
459 }
460 
461 static switch_status_t _timerfd_step(switch_timer_t *timer)
462 {
463  timer->tick++;
464  timer->samplecount += timer->samples;
465 
466  return SWITCH_STATUS_SUCCESS;
467 }
468 
469 static switch_status_t _timerfd_next(switch_timer_t *timer)
470 {
471  interval_timer_t *it = timer->private_info;
472  uint64_t u64 = 0;
473 
474  if (read(it->fd, &u64, sizeof(u64)) < 0) {
475  return SWITCH_STATUS_GENERR;
476  } else {
477  timer->tick += u64;
478  timer->samplecount = timer->tick * timer->samples;
479  }
480 
481  return SWITCH_STATUS_SUCCESS;
482 }
483 
484 static switch_status_t _timerfd_check(switch_timer_t *timer, switch_bool_t step)
485 {
486  interval_timer_t *it = timer->private_info;
487  struct itimerspec val;
488  int diff;
489 
490  timerfd_gettime(it->fd, &val);
491  diff = val.it_interval.tv_nsec / 1000;
492 
493  if (diff > 0) {
494  /* still pending */
495  timer->diff = diff;
496  return SWITCH_STATUS_FALSE;
497  } else {
498  /* timer pending */
499  timer->diff = 0;
500  if (step) {
501  _timerfd_step(timer);
502  }
503  return SWITCH_STATUS_SUCCESS;
504  }
505 }
506 
507 static switch_status_t _timerfd_destroy(switch_timer_t *timer)
508 {
509  interval_timer_t *it = timer->private_info;
510  int rc;
511 
512  rc = timerfd_stop_interval(it);
513  return rc;
514 }
515 
516 #endif
517 ////////
518 
519 
520 static switch_time_t time_now(int64_t offset)
521 {
522  switch_time_t now;
523 
524 #if (defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)) || defined(WIN32)
525  if (MONO) {
526 #ifndef WIN32
527  struct timespec ts;
528  clock_gettime(offset ? CLOCK_MONOTONIC : CLOCK_REALTIME, &ts);
529  if (offset < 0) offset = 0;
530  now = ts.tv_sec * APR_USEC_PER_SEC + (ts.tv_nsec / 1000) + offset;
531 #else
532  if (offset == 0) {
533  return switch_time_now();
534  } else if (offset < 0) offset = 0;
535 
536 
537  if (win32_use_qpc) {
538  /* Use QueryPerformanceCounter */
539  uint64_t count = 0;
540  QueryPerformanceCounter((LARGE_INTEGER*)&count);
541  now = ((count * 1000000) / win32_qpc_freq) + offset;
542  } else {
543  /* Use good old timeGetTime() */
544  DWORD tick_now;
545  DWORD tick_diff;
546 
547  tick_now = timeGetTime();
548  if (win32_tick_time_since_start != -1) {
549  EnterCriticalSection(&timer_section);
550  /* just add diff (to make it work more than 50 days). */
551  tick_diff = tick_now - win32_last_get_time_tick;
552  win32_tick_time_since_start += tick_diff;
553 
554  win32_last_get_time_tick = tick_now;
555  now = (win32_tick_time_since_start * 1000) + offset;
556  LeaveCriticalSection(&timer_section);
557  } else {
558  /* If someone is calling us before timer is initialized,
559  * return the current tick + offset
560  */
561  now = (tick_now * 1000) + offset;
562  }
563  }
564 #endif
565  } else {
566 #endif
567  now = switch_time_now();
568 
569 #if (defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)) || defined(WIN32)
570  }
571 #endif
572 
573  return now;
574 }
575 
577 {
578  if (SYSTEM_TIME) {
579  /* Return system time reference */
580  return time_now(0);
581  } else {
582  /* Return monotonic time reference (when available) */
584  }
585 }
586 
588 
590 {
591  runtime.time_sync++; /* Indicate that we are syncing time right now */
592 
594 
595  if (SYSTEM_TIME) {
597  runtime.offset = 0;
598  } else {
599  runtime.offset = runtime.reference - switch_mono_micro_time_now(); /* Get the offset between system time and the monotonic clock (when available) */
601  }
602 
603  if (runtime.reference - last_time > 1000000 || last_time == 0) {
604  if (SYSTEM_TIME) {
605  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Clock is already configured to always report system time.\n");
606  } else {
607  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Clock synchronized to system time.\n");
608  }
609  }
610  last_time = runtime.reference;
611 
612  runtime.time_sync++; /* Indicate that we are finished syncing time */
613 }
614 
616 {
617  do_sleep(t);
618 }
619 
621 {
622 
623  if (globals.RUNNING != 1 || t < 1000 || t >= 10000) {
624  do_sleep(t);
625  return;
626  }
627 #ifndef DISABLE_1MS_COND
628  if (globals.use_cond_yield == 1) {
630  return;
631  }
632 #endif
633 
634  do_sleep(t);
635 }
636 
637 
639 {
640  if (runtime.tipping_point && globals.timer_count >= runtime.tipping_point) {
641  switch_os_yield();
642  return;
643  }
644 #ifdef DISABLE_1MS_COND
645  do_sleep(1000);
646 #else
647  if (globals.RUNNING != 1 || !runtime.timestamp || globals.use_cond_yield != 1) {
648  do_sleep(1000);
649  return;
650  }
651  switch_mutex_lock(TIMER_MATRIX[1].mutex);
652  switch_thread_cond_wait(TIMER_MATRIX[1].cond, TIMER_MATRIX[1].mutex);
653  switch_mutex_unlock(TIMER_MATRIX[1].mutex);
654 #endif
655 }
656 
658 {
659  switch_time_t want;
660  if (!t)
661  return;
662 
663  if (globals.RUNNING != 1 || !runtime.timestamp || globals.use_cond_yield != 1) {
664  do_sleep(t);
665  return;
666  }
667  want = runtime.timestamp + t;
668  while (globals.RUNNING == 1 && globals.use_cond_yield == 1 && runtime.timestamp < want) {
669  switch_mutex_lock(TIMER_MATRIX[1].mutex);
670  if (runtime.timestamp < want) {
671  switch_thread_cond_wait(TIMER_MATRIX[1].cond, TIMER_MATRIX[1].mutex);
672  }
673  switch_mutex_unlock(TIMER_MATRIX[1].mutex);
674  }
675 
676 
677 }
678 
680 {
681  timer_private_t *private_info;
682  int sanity = 0;
683 
684  timer->start = switch_micro_time_now();
685 
686  if (timer->interval == 1) {
688  switch_mutex_lock(globals.mutex);
689  globals.timer_count++;
691  return SWITCH_STATUS_SUCCESS;
692  }
693 
694 #ifdef HAVE_TIMERFD_CREATE
695  if (TFD == 2) {
696  return _timerfd_init(timer);
697  }
698 #endif
699 
700  while (globals.STARTED == 0) {
701  do_sleep(100000);
702  if (++sanity == 300) {
703  abort();
704  }
705  }
706 
707  if (globals.RUNNING != 1 || !globals.mutex || timer->interval < 1) {
708  return SWITCH_STATUS_FALSE;
709  }
710 
711  if ((private_info = switch_core_alloc(timer->memory_pool, sizeof(*private_info)))) {
712  switch_mutex_lock(globals.mutex);
713  if (!TIMER_MATRIX[timer->interval].mutex) {
715  switch_thread_cond_create(&TIMER_MATRIX[timer->interval].cond, module_pool);
716  }
717  TIMER_MATRIX[timer->interval].count++;
719  timer->private_info = private_info;
720  private_info->start = private_info->reference = (switch_size_t)TIMER_MATRIX[timer->interval].tick;
721  private_info->start -= 2; /* switch_core_timer_init sets samplecount to samples, this makes first next() step once */
722  private_info->roll = TIMER_MATRIX[timer->interval].roll;
723  private_info->ready = 1;
724 
725  if (runtime.microseconds_per_tick > 10000 && (timer->interval % (int)(runtime.microseconds_per_tick / 1000)) != 0 && (timer->interval % 10) == 0) {
726  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Increasing global timer resolution to 10ms to handle interval %d\n", timer->interval);
728  }
729 
730  if (timer->interval > 0 && (timer->interval < (int)(runtime.microseconds_per_tick / 1000) || (timer->interval % 10) != 0)) {
731  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Increasing global timer resolution to 1ms to handle interval %d\n", timer->interval);
734  }
735 
736  switch_mutex_lock(globals.mutex);
737  globals.timer_count++;
738  if (runtime.tipping_point && globals.timer_count == (runtime.tipping_point + 1)) {
739  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Crossed tipping point of %u, shifting into high-gear.\n", runtime.tipping_point);
740  }
742 
743  return SWITCH_STATUS_SUCCESS;
744  }
745 
746  return SWITCH_STATUS_MEMERR;
747 }
748 
749 #define check_roll() if (private_info->roll < TIMER_MATRIX[timer->interval].roll) { \
750  private_info->roll++; \
751  private_info->reference = private_info->start = (switch_size_t)TIMER_MATRIX[timer->interval].tick; \
752  private_info->start--; /* Must have a diff */ \
753  } \
754 
755 
757 {
758  timer_private_t *private_info;
759  uint64_t samples;
760 
761  if (timer->interval == 1) {
762  return SWITCH_STATUS_FALSE;
763  }
764 
765 #ifdef HAVE_TIMERFD_CREATE
766  if (TFD == 2) {
767  return _timerfd_step(timer);
768  }
769 #endif
770 
771  private_info = timer->private_info;
772 
773  if (globals.RUNNING != 1 || private_info->ready == 0) {
774  return SWITCH_STATUS_FALSE;
775  }
776 
777  check_roll();
778  samples = (uint64_t)timer->samples * (private_info->reference - private_info->start);
779 
780  if (samples > UINT32_MAX) {
781  private_info->start = private_info->reference - 1; /* Must have a diff */
782  samples = timer->samples;
783  }
784 
785  timer->samplecount = (uint32_t) samples;
786  private_info->reference++;
787 
788  return SWITCH_STATUS_SUCCESS;
789 }
790 
792 {
793  timer_private_t *private_info;
794 
795  if (timer->interval == 1) {
796  return timer_generic_sync(timer);
797  }
798 
799 #ifdef HAVE_TIMERFD_CREATE
800  if (TFD == 2) {
801  return timer_generic_sync(timer);
802  }
803 #endif
804 
805  private_info = timer->private_info;
806 
807  if (globals.RUNNING != 1 || private_info->ready == 0) {
808  return SWITCH_STATUS_FALSE;
809  }
810 
811  /* sync the clock */
812  private_info->reference = (switch_size_t)(timer->tick = TIMER_MATRIX[timer->interval].tick);
813 
814  /* apply timestamp */
815  timer_step(timer);
816 
817  return SWITCH_STATUS_SUCCESS;
818 }
819 
820 
822 {
823  timer_private_t *private_info;
824 
825 #ifdef DISABLE_1MS_COND
826  int cond_index = timer->interval;
827 #else
828  int cond_index = 1;
829 #endif
830  int delta;
831 
832  if (timer->interval == 1) {
833  return SWITCH_STATUS_FALSE;
834  }
835 
836 #ifdef HAVE_TIMERFD_CREATE
837  if (TFD == 2) {
838  return _timerfd_next(timer);
839  }
840 #endif
841 
842  private_info = timer->private_info;
843 
844  delta = (int) (private_info->reference - TIMER_MATRIX[timer->interval].tick);
845 
846 
847 
848  /* sync up timer if it's not been called for a while otherwise it will return instantly several times until it catches up */
849  if (delta < -1) {
850  private_info->reference = (switch_size_t)(timer->tick = TIMER_MATRIX[timer->interval].tick);
851  }
852  timer_step(timer);
853 
854  if (!MATRIX) {
855  do_sleep(1000 * timer->interval);
856  goto end;
857  }
858 
859  while (globals.RUNNING == 1 && private_info->ready && TIMER_MATRIX[timer->interval].tick < private_info->reference) {
860  check_roll();
861 
862  switch_os_yield();
863 
864 
865  if (runtime.tipping_point && globals.timer_count >= runtime.tipping_point) {
866  globals.use_cond_yield = 0;
867  } else {
868  if (globals.use_cond_yield == 1) {
869  switch_mutex_lock(TIMER_MATRIX[cond_index].mutex);
870  if (TIMER_MATRIX[timer->interval].tick < private_info->reference) {
871  switch_thread_cond_wait(TIMER_MATRIX[cond_index].cond, TIMER_MATRIX[cond_index].mutex);
872  }
873  switch_mutex_unlock(TIMER_MATRIX[cond_index].mutex);
874  } else {
875  do_sleep(1000);
876  }
877  }
878  }
879 
880  end:
881  return globals.RUNNING == 1 ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
882 }
883 
885 {
886  timer_private_t *private_info;
888 
889  if (timer->interval == 1) {
890  return SWITCH_STATUS_FALSE;
891  }
892 
893 #ifdef HAVE_TIMERFD_CREATE
894  if (TFD == 2) {
895  return _timerfd_check(timer, step);
896  }
897 #endif
898 
899  private_info = timer->private_info;
900 
901  if (globals.RUNNING != 1 || !private_info->ready) {
902  return SWITCH_STATUS_SUCCESS;
903  }
904 
905  check_roll();
906 
907  timer->tick = TIMER_MATRIX[timer->interval].tick;
908 
909  if (timer->tick < private_info->reference) {
910  timer->diff = (switch_size_t)(private_info->reference - timer->tick);
911  } else {
912  timer->diff = 0;
913  }
914 
915  if (timer->diff) {
916  status = SWITCH_STATUS_FALSE;
917  } else if (step) {
918  timer_step(timer);
919  }
920 
921 
922  return status;
923 }
924 
926 {
927  timer_private_t *private_info;
928 
929  if (timer->interval == 1) {
930  switch_mutex_lock(globals.mutex);
931  if (globals.timer_count) {
932  globals.timer_count--;
933  }
935  return SWITCH_STATUS_SUCCESS;
936  }
937 
938 #ifdef HAVE_TIMERFD_CREATE
939  if (TFD == 2) {
940  return _timerfd_destroy(timer);
941  }
942 #endif
943 
944  private_info = timer->private_info;
945 
946  if (timer->interval < MAX_ELEMENTS) {
947  switch_mutex_lock(globals.mutex);
948  TIMER_MATRIX[timer->interval].count--;
949  if (TIMER_MATRIX[timer->interval].count == 0) {
950  TIMER_MATRIX[timer->interval].tick = 0;
951  }
953  }
954  if (private_info) {
955  private_info->ready = 0;
956  }
957 
958  switch_mutex_lock(globals.mutex);
959  if (globals.timer_count) {
960  globals.timer_count--;
961  if (runtime.tipping_point && globals.timer_count == (runtime.tipping_point - 1)) {
962  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Fell Below tipping point of %u, shifting into low-gear.\n", runtime.tipping_point);
963  }
964  }
966 
967  return SWITCH_STATUS_SUCCESS;
968 }
969 
970 static void win32_init_timers(void)
971 {
972 #ifdef WIN32
973  OSVERSIONINFOEX version_info; /* Used to fetch current OS version from Windows */
974 
975  EnterCriticalSection(&timer_section);
976 
977  ZeroMemory(&version_info, sizeof(OSVERSIONINFOEX));
978  version_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
979 
980  /* Check if we should use timeGetTime() (pre-Vista) or QueryPerformanceCounter() (Vista and later) */
981 
982  if (GetVersionEx((OSVERSIONINFO*) &version_info)) {
983  if (version_info.dwPlatformId == VER_PLATFORM_WIN32_NT && version_info.dwMajorVersion >= 6) {
984  if (QueryPerformanceFrequency((LARGE_INTEGER*)&win32_qpc_freq) && win32_qpc_freq > 0) {
985  /* At least Vista, and QueryPerformanceFrequency() suceeded, enable qpc */
986  win32_use_qpc = 1;
987  } else {
988  /* At least Vista, but QueryPerformanceFrequency() failed, disable qpc */
989  win32_use_qpc = 0;
990  }
991  } else {
992  /* Older then Vista, disable qpc */
993  win32_use_qpc = 0;
994  }
995  } else {
996  /* Unknown version - we want at least Vista, disable qpc */
997  win32_use_qpc = 0;
998  }
999 
1000  if (win32_use_qpc) {
1001  uint64_t count = 0;
1002 
1003  if (!QueryPerformanceCounter((LARGE_INTEGER*)&count) || count == 0) {
1004  /* Call to QueryPerformanceCounter() failed, disable qpc again */
1005  win32_use_qpc = 0;
1006  }
1007  }
1008 
1009  if (!win32_use_qpc) {
1010  /* This will enable timeGetTime() instead, qpc init failed */
1011  win32_last_get_time_tick = timeGetTime();
1012  win32_tick_time_since_start = win32_last_get_time_tick;
1013  }
1014 
1015  LeaveCriticalSection(&timer_section);
1016 #endif
1017 }
1018 
1020 {
1021  switch_time_t too_late = runtime.microseconds_per_tick * 1000;
1022  uint32_t current_ms = 0;
1023  uint32_t x, tick = 0, sps_interval_ticks = 0;
1024  switch_time_t ts = 0, last = 0;
1025  int fwd_errs = 0, rev_errs = 0;
1026  int profile_tick = 0;
1027  int tfd = -1;
1028  uint32_t time_sync = runtime.time_sync;
1029 
1030 #ifdef HAVE_TIMERFD_CREATE
1031  int last_MICROSECONDS_PER_TICK = runtime.microseconds_per_tick;
1032 
1033  struct itimerspec spec = { { 0 } };
1034 
1035  if (MONO && TFD) {
1036  tfd = timerfd_create(CLOCK_MONOTONIC, 0);
1037 
1038  if (tfd > -1) {
1039  spec.it_interval.tv_sec = 0;
1040  spec.it_interval.tv_nsec = runtime.microseconds_per_tick * 1000;
1041  spec.it_value.tv_sec = 0;
1042  spec.it_value.tv_nsec = 100000;
1043 
1044  if (timerfd_settime(tfd, 0, &spec, NULL)) {
1045  close(tfd);
1046  tfd = -1;
1047  }
1048  }
1049 
1050  if (tfd > -1) MATRIX = 0;
1051  }
1052 #else
1053  tfd = -1;
1054 #endif
1055 
1058 
1059  if (runtime.timer_affinity > -1) {
1061  }
1062 
1063  switch_time_sync();
1064  time_sync = runtime.time_sync;
1065 
1066  globals.STARTED = globals.RUNNING = 1;
1070 
1071  if (MONO) {
1072  int loops;
1073  for (loops = 0; loops < 3; loops++) {
1074  ts = switch_time_ref();
1075  /* if it returns the same value every time it won't be of much use. */
1076  if (ts == last) {
1077  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Broken MONOTONIC Clock Detected!, Support Disabled.\n");
1078  MONO = 0;
1079  NANO = 0;
1082  break;
1083  }
1085  last = ts;
1086  }
1087  }
1088 
1089  ts = 0;
1090  last = 0;
1091  fwd_errs = rev_errs = 0;
1092 
1093 #ifndef DISABLE_1MS_COND
1094  if (!NANO) {
1096  switch_thread_cond_create(&TIMER_MATRIX[1].cond, module_pool);
1097  }
1098 #endif
1099 
1100 
1101  switch_time_sync();
1102  time_sync = runtime.time_sync;
1103 
1104  globals.use_cond_yield = COND;
1105  globals.RUNNING = 1;
1106 
1107  while (globals.RUNNING == 1) {
1108 
1109 #ifdef HAVE_TIMERFD_CREATE
1110  if (last_MICROSECONDS_PER_TICK != runtime.microseconds_per_tick) {
1111  spec.it_interval.tv_nsec = runtime.microseconds_per_tick * 1000;
1112  timerfd_settime(tfd, 0, &spec, NULL);
1113  }
1114 
1115  last_MICROSECONDS_PER_TICK = runtime.microseconds_per_tick;
1116 #endif
1117 
1119 
1120  while (((ts = time_now(runtime.offset)) + 100) < runtime.reference) {
1121  if (ts < last) {
1122  if (MONO) {
1124 
1125  if (time_sync == runtime.time_sync) { /* Only resync if not in the middle of switch_time_sync() already */
1126  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Virtual Migration Detected! Syncing Clock\n");
1127  win32_init_timers(); /* Make sure to reinit timers on WIN32 */
1128  switch_time_sync();
1129  time_sync = runtime.time_sync;
1130  }
1131  } else {
1132  int64_t diff = (int64_t) (ts - last);
1133  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Reverse Clock Skew Detected!\n");
1135  current_ms = 0;
1136  tick = 0;
1137  runtime.initiated += diff;
1138  rev_errs++;
1139  }
1140 
1141  if (!MONO || time_sync == runtime.time_sync) {
1142 #if defined(HAVE_CLOCK_NANOSLEEP)
1144  "If you see this message many times try setting the param enable-clock-nanosleep to true in switch.conf.xml or consider a nicer machine to run me on. I AM *FREE* afterall.\n");
1145 #else
1147  "If you see this message many times consider a nicer machine to run me on. I AM *FREE* afterall.\n");
1148 #endif
1149  }
1150  } else {
1151  rev_errs = 0;
1152  }
1153 
1154  if (runtime.tipping_point && globals.timer_count >= runtime.tipping_point) {
1155  switch_os_yield();
1156  } else {
1157  if (tfd > -1 && globals.RUNNING == 1) {
1158  uint64_t exp;
1159  int r;
1160  r = read(tfd, &exp, sizeof(exp));
1161  r++;
1162  } else {
1163  switch_time_t timediff = runtime.reference - ts;
1164 
1165  if (runtime.microseconds_per_tick < timediff) {
1166  /* Only sleep for runtime.microseconds_per_tick if this value is lower then the actual time diff we need to sleep */
1168  } else {
1169 #ifdef WIN32
1170  /* Windows only sleeps in ms precision, try to round the usec value as good as possible */
1171  do_sleep((switch_interval_time_t)floor((timediff / 1000.0) + 0.5) * 1000);
1172 #else
1173  do_sleep(timediff);
1174 #endif
1175  }
1176  }
1177  }
1178 
1179  last = ts;
1180  }
1181 
1182  if (ts > (runtime.reference + too_late)) {
1183  if (MONO) {
1185 
1186  if (time_sync == runtime.time_sync) { /* Only resync if not in the middle of switch_time_sync() already */
1187  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Virtual Migration Detected! Syncing Clock\n");
1188  win32_init_timers(); /* Make sure to reinit timers on WIN32 */
1189  switch_time_sync();
1190  time_sync = runtime.time_sync;
1191  }
1192  } else {
1194  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Forward Clock Skew Detected!\n");
1195  fwd_errs++;
1197  current_ms = 0;
1198  tick = 0;
1199  runtime.initiated += diff;
1200  }
1201  } else {
1202  fwd_errs = 0;
1203  }
1204 
1205  if (fwd_errs > 9 || rev_errs > 9) {
1206  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Auto Re-Syncing clock.\n");
1207  switch_time_sync();
1208  time_sync = runtime.time_sync;
1209  fwd_errs = rev_errs = 0;
1210  }
1211 
1212  runtime.timestamp = ts;
1213  current_ms += (runtime.microseconds_per_tick / 1000);
1214  tick++;
1215 
1216  if (time_sync < runtime.time_sync) {
1217  time_sync++; /* Only step once for each loop, we want to make sure to keep this thread safe */
1218  }
1219 
1220  if (tick >= (1000000 / runtime.microseconds_per_tick)) {
1221  if (++profile_tick == 1) {
1223  profile_tick = 0;
1224  }
1225 
1226  if (runtime.sps <= 0) {
1227  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Over Session Rate of %d!\n", runtime.sps_total);
1228  }
1231 
1232  if (sps_interval_ticks >= 300) {
1234  sps_interval_ticks = 0;
1238  }
1239 
1240  sps_interval_ticks++;
1241 
1244  }
1245 
1246  if (runtime.sps_last > runtime.sps_peak) {
1248  }
1251  tick = 0;
1252  }
1253 #ifndef DISABLE_1MS_COND
1254  TIMER_MATRIX[1].tick++;
1255  if (switch_mutex_trylock(TIMER_MATRIX[1].mutex) == SWITCH_STATUS_SUCCESS) {
1256  switch_thread_cond_broadcast(TIMER_MATRIX[1].cond);
1257  switch_mutex_unlock(TIMER_MATRIX[1].mutex);
1258  }
1259  if (TIMER_MATRIX[1].tick == MAX_TICK) {
1260  TIMER_MATRIX[1].tick = 0;
1261  TIMER_MATRIX[1].roll++;
1262  }
1263 #endif
1264 
1265 
1266  if (MATRIX && (current_ms % (runtime.microseconds_per_tick / 1000)) == 0) {
1267  for (x = (runtime.microseconds_per_tick / 1000); x <= MAX_ELEMENTS; x += (runtime.microseconds_per_tick / 1000)) {
1268  if ((current_ms % x) == 0) {
1269  if (TIMER_MATRIX[x].count) {
1270  TIMER_MATRIX[x].tick++;
1271 #ifdef DISABLE_1MS_COND
1272 
1273  if (TIMER_MATRIX[x].mutex && switch_mutex_trylock(TIMER_MATRIX[x].mutex) == SWITCH_STATUS_SUCCESS) {
1274  switch_thread_cond_broadcast(TIMER_MATRIX[x].cond);
1275  switch_mutex_unlock(TIMER_MATRIX[x].mutex);
1276  }
1277 #endif
1278  if (TIMER_MATRIX[x].tick == MAX_TICK) {
1279  TIMER_MATRIX[x].tick = 0;
1280  TIMER_MATRIX[x].roll++;
1281  }
1282  }
1283  }
1284  }
1285  }
1286 
1287  if (current_ms == MAX_ELEMENTS) {
1288  current_ms = 0;
1289  }
1290  }
1291 
1292  globals.use_cond_yield = 0;
1293 
1294  for (x = (runtime.microseconds_per_tick / 1000); x <= MAX_ELEMENTS; x += (runtime.microseconds_per_tick / 1000)) {
1295  if (TIMER_MATRIX[x].mutex && switch_mutex_trylock(TIMER_MATRIX[x].mutex) == SWITCH_STATUS_SUCCESS) {
1296  switch_thread_cond_broadcast(TIMER_MATRIX[x].cond);
1297  switch_mutex_unlock(TIMER_MATRIX[x].mutex);
1298  }
1299  }
1300 
1301  if (tfd > -1) {
1302  close(tfd);
1303  tfd = -1;
1304  }
1305 
1306 
1307  switch_mutex_lock(globals.mutex);
1308  globals.RUNNING = 0;
1310 
1312 
1313  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Soft timer thread exiting.\n");
1314 
1315  return SWITCH_STATUS_TERM;
1316 }
1317 
1318 /*
1319  This converts a struct tm to a switch_time_exp_t
1320  We have to use UNIX structures to do our exams
1321  and use switch_* functions for the output.
1322 */
1323 
1324 static void tm2switchtime(struct tm *tm, switch_time_exp_t *xt)
1325 {
1326 
1327  if (!xt || !tm) {
1328  return;
1329  }
1330  memset(xt, 0, sizeof(*xt));
1331 
1332  xt->tm_sec = tm->tm_sec;
1333  xt->tm_min = tm->tm_min;
1334  xt->tm_hour = tm->tm_hour;
1335  xt->tm_mday = tm->tm_mday;
1336  xt->tm_mon = tm->tm_mon;
1337  xt->tm_year = tm->tm_year;
1338  xt->tm_wday = tm->tm_wday;
1339  xt->tm_yday = tm->tm_yday;
1340  xt->tm_isdst = tm->tm_isdst;
1341 
1342 #if defined(HAVE_STRUCT_TM_TM_GMTOFF)
1343  xt->tm_gmtoff = tm->tm_gmtoff;
1344 #endif
1345 
1346  return;
1347 }
1348 
1349 /* **************************************************************************
1350  LOADING OF THE XML DATA - HASH TABLE & MEMORY POOL MANAGEMENT
1351  ************************************************************************** */
1352 
1353 typedef struct {
1357 
1359 static switch_event_node_t *NODE = NULL;
1360 
1361 SWITCH_DECLARE(const char *) switch_lookup_timezone(const char *tz_name)
1362 {
1363  char *value = NULL;
1364 
1365  if (zstr(tz_name) || !TIMEZONES_LIST.hash) {
1366  return NULL;
1367  }
1368 
1369  if ((value = switch_core_hash_find(TIMEZONES_LIST.hash, tz_name)) == NULL) {
1370  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Timezone '%s' not found!\n", tz_name);
1371  }
1372 
1373  return value;
1374 }
1375 
1377 {
1378  switch_xml_t xml = NULL, x_lists = NULL, x_list = NULL, cfg = NULL;
1379  unsigned total = 0;
1380 
1381  if (TIMEZONES_LIST.hash) {
1382  switch_core_hash_destroy(&TIMEZONES_LIST.hash);
1383  }
1384 
1385  if (TIMEZONES_LIST.pool) {
1386  switch_core_destroy_memory_pool(&TIMEZONES_LIST.pool);
1387  }
1388 
1389  memset(&TIMEZONES_LIST, 0, sizeof(TIMEZONES_LIST));
1390  switch_core_new_memory_pool(&TIMEZONES_LIST.pool);
1391  switch_core_hash_init(&TIMEZONES_LIST.hash);
1392 
1393  if ((xml = switch_xml_open_cfg("timezones.conf", &cfg, NULL))) {
1394  if ((x_lists = switch_xml_child(cfg, "timezones"))) {
1395  for (x_list = switch_xml_child(x_lists, "zone"); x_list; x_list = x_list->next) {
1396  const char *name = switch_xml_attr(x_list, "name");
1397  const char *value = switch_xml_attr(x_list, "value");
1398 
1399  if (zstr(name)) {
1400  continue;
1401  }
1402 
1403  if (zstr(value)) {
1404  continue;
1405  }
1406 
1407  switch_core_hash_insert(TIMEZONES_LIST.hash, name, switch_core_strdup(TIMEZONES_LIST.pool, value));
1408  total++;
1409  }
1410  }
1411 
1412  switch_xml_free(xml);
1413  }
1414 
1415  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Timezone %sloaded %d definitions\n", reload ? "re" : "", total);
1416 }
1417 
1418 static void event_handler(switch_event_t *event)
1419 {
1420  switch_mutex_lock(globals.mutex);
1423 }
1424 
1425 static void tztime(const time_t *const timep, const char *tzstring, struct tm *const tmp);
1426 
1428 {
1429  struct tm xtm = { 0 };
1430  const char *tz_name = tz;
1431  const char *tzdef;
1432  time_t timep;
1433 
1434  if (!thetime) {
1435  thetime = switch_micro_time_now();
1436  }
1437 
1438  timep = (thetime) / (int64_t) (1000000);
1439 
1440  if (!zstr(tz_name)) {
1441  tzdef = switch_lookup_timezone(tz_name);
1442  } else {
1443  /* We set the default timezone to GMT. */
1444  tz_name = "GMT";
1445  tzdef = "GMT";
1446  }
1447 
1448  if (tzdef) { /* The lookup of the zone may fail. */
1449  tztime(&timep, tzdef, &xtm);
1450  tm2switchtime(&xtm, tm);
1451  return SWITCH_STATUS_SUCCESS;
1452  }
1453 
1454  return SWITCH_STATUS_FALSE;
1455 
1456 }
1457 
1458 SWITCH_DECLARE(switch_status_t) switch_strftime_tz(const char *tz, const char *format, char *date, size_t len, switch_time_t thetime)
1459 {
1460  time_t timep;
1461 
1462  const char *tz_name = tz;
1463  const char *tzdef;
1464 
1465  switch_size_t retsize;
1466 
1467  struct tm tm = { 0 };
1468  switch_time_exp_t stm;
1469 
1470  if (!thetime) {
1471  thetime = switch_micro_time_now();
1472  }
1473 
1474  timep = (thetime) / (int64_t) (1000000);
1475 
1476  if (!zstr(tz_name)) {
1477  tzdef = switch_lookup_timezone(tz_name);
1478  } else {
1479  /* We set the default timezone to GMT. */
1480  tz_name = "GMT";
1481  tzdef = "GMT";
1482  }
1483 
1484  if (tzdef) { /* The lookup of the zone may fail. */
1485  tztime(&timep, tzdef, &tm);
1486  tm2switchtime(&tm, &stm);
1487  switch_strftime_nocheck(date, &retsize, len, zstr(format) ? "%Y-%m-%d %T" : format, &stm);
1488  if (!zstr_buf(date)) {
1489  return SWITCH_STATUS_SUCCESS;
1490  }
1491  }
1492  return SWITCH_STATUS_FALSE;
1493 }
1494 
1496 {
1497  switch_timer_interface_t *timer_interface;
1498  module_pool = pool;
1499 
1500 #ifdef WIN32
1501  timeBeginPeriod(1);
1502 
1503  InitializeCriticalSection(&timer_section);
1504 
1505  win32_init_timers(); /* Init timers for Windows, if we should use timeGetTime() or QueryPerformanceCounters() */
1506 #endif
1507 
1508  memset(&globals, 0, sizeof(globals));
1510 
1513  }
1515 
1516  /* connect my internal structure to the blank pointer passed to me */
1517  *module_interface = switch_loadable_module_create_module_interface(pool, modname);
1518  timer_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_TIMER_INTERFACE);
1519  timer_interface->interface_name = "soft";
1520  timer_interface->timer_init = timer_init;
1521  timer_interface->timer_next = timer_next;
1522  timer_interface->timer_step = timer_step;
1523  timer_interface->timer_sync = timer_sync;
1524  timer_interface->timer_check = timer_check;
1525  timer_interface->timer_destroy = timer_destroy;
1526 
1529  }
1530 
1533  }
1534 
1535  if (TFD) {
1537  }
1538 
1539 #ifdef WIN32
1541  MONO = 1;
1542 
1543  if (win32_use_qpc) {
1544  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Enabled Windows monotonic clock, using QueryPerformanceCounter()\n");
1545  } else {
1546  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Enabled Windows monotonic clock, using timeGetTime()\n");
1547  }
1548 
1549  runtime.initiated = switch_mono_micro_time_now(); /* Update mono_initiated, since now is the first time the real clock is enabled */
1550  }
1551 
1552  /* No need to calibrate clock in Win32, we will only sleep ms anyway, it's just not accurate enough */
1554 #endif
1555 
1557  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Calibrating timer, please wait...\n");
1559  } else {
1560  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Clock calibration disabled.\n");
1561  }
1562 
1563  /* indicate that the module should continue to be loaded */
1564  return SWITCH_STATUS_SUCCESS;
1565 }
1566 
1568 {
1569  globals.use_cond_yield = 0;
1570 
1571  if (globals.RUNNING == 1) {
1572  switch_mutex_lock(globals.mutex);
1573  globals.RUNNING = -1;
1575 
1576  while (globals.RUNNING == -1) {
1577  do_sleep(10000);
1578  }
1579  }
1580 #if defined(WIN32)
1581  timeEndPeriod(1);
1582  win32_tick_time_since_start = -1; /* we are not initialized anymore */
1583  DeleteCriticalSection(&timer_section);
1584 #endif
1585 
1586  if (TIMEZONES_LIST.hash) {
1587  switch_core_hash_destroy(&TIMEZONES_LIST.hash);
1588  }
1589 
1590  if (TIMEZONES_LIST.pool) {
1591  switch_core_destroy_memory_pool(&TIMEZONES_LIST.pool);
1592  }
1593 
1594  if (NODE) {
1595  switch_event_unbind(&NODE);
1596  }
1597 
1598  return SWITCH_STATUS_SUCCESS;
1599 }
1600 
1601 
1602 
1603 
1604 /*
1605  * This file was originally written for NetBSD and is in the public domain,
1606  * so clarified as of 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
1607  *
1608  * Iw was modified by Massimo Cetra in order to be used with Callweaver and Freeswitch.
1609  */
1610 
1611 //#define TESTING_IT 1
1612 
1613 #include <stdlib.h>
1614 #include <stdio.h>
1615 #include <time.h>
1616 #include <string.h>
1617 #include <assert.h>
1618 
1619 
1620 #ifdef TESTING_IT
1621 #include <sys/time.h>
1622 #endif
1623 
1624 
1625 #ifndef TRUE
1626 #define TRUE 1
1627 #endif /* !defined TRUE */
1628 
1629 #ifndef FALSE
1630 #define FALSE 0
1631 #endif /* !defined FALSE */
1632 
1633 
1634 
1635 #ifndef TZ_MAX_TIMES
1636 /*
1637 ** The TZ_MAX_TIMES value below is enough to handle a bit more than a
1638 ** year's worth of solar time (corrected daily to the nearest second) or
1639 ** 138 years of Pacific Presidential Election time
1640 ** (where there are three time zone transitions every fourth year).
1641 */
1642 #define TZ_MAX_TIMES 370
1643 #endif /* !defined TZ_MAX_TIMES */
1644 
1645 #ifndef TZ_MAX_TYPES
1646 
1647 #ifndef NOSOLAR
1648 #define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
1649 #endif /* !defined NOSOLAR */
1650 
1651 #ifdef NOSOLAR
1652 /*
1653 ** Must be at least 14 for Europe/Riga as of Jan 12 1995,
1654 ** as noted by Earl Chew <earl@hpato.aus.hp.com>.
1655 */
1656 #define TZ_MAX_TYPES 20 /* Maximum number of local time types */
1657 #endif /* !defined NOSOLAR */
1658 
1659 #endif /* !defined TZ_MAX_TYPES */
1660 
1661 #ifndef TZ_MAX_CHARS
1662 #define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
1663  /* (limited by what unsigned chars can hold) */
1664 #endif /* !defined TZ_MAX_CHARS */
1665 
1666 #ifndef TZ_MAX_LEAPS
1667 #define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
1668 #endif /* !defined TZ_MAX_LEAPS */
1669 
1670 #ifdef TZNAME_MAX
1671 #define MY_TZNAME_MAX TZNAME_MAX
1672 #endif /* defined TZNAME_MAX */
1673 
1674 #ifndef TZNAME_MAX
1675 #define MY_TZNAME_MAX 255
1676 #endif /* !defined TZNAME_MAX */
1677 
1678 
1679 #define SECSPERMIN 60
1680 #define MINSPERHOUR 60
1681 #define HOURSPERDAY 24
1682 #define DAYSPERWEEK 7
1683 #define DAYSPERNYEAR 365
1684 #define DAYSPERLYEAR 366
1685 #define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
1686 #define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY)
1687 #define MONSPERYEAR 12
1688 
1689 #define JULIAN_DAY 0 /* Jn - Julian day */
1690 #define DAY_OF_YEAR 1 /* n - day of year */
1691 #define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
1692 
1693 #define EPOCH_YEAR 1970
1694 #define EPOCH_WDAY TM_THURSDAY
1695 
1696 
1697 #ifndef TZ_MAX_TIMES
1698 /*
1699 ** The TZ_MAX_TIMES value below is enough to handle a bit more than a
1700 ** year's worth of solar time (corrected daily to the nearest second) or
1701 ** 138 years of Pacific Presidential Election time
1702 ** (where there are three time zone transitions every fourth year).
1703 */
1704 #define TZ_MAX_TIMES 370
1705 #endif /* !defined TZ_MAX_TIMES */
1706 
1707 #ifndef TZDEFRULES
1708 #define TZDEFRULES "posixrules"
1709 #endif /* !defined TZDEFRULES */
1710 
1711 /*
1712 ** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
1713 ** We default to US rules as of 1999-08-17.
1714 ** POSIX 1003.1 section 8.1.1 says that the default DST rules are
1715 ** implementation dependent; for historical reasons, US rules are a
1716 ** common default.
1717 */
1718 #ifndef TZDEFRULESTRING
1719 #define TZDEFRULESTRING ",M4.1.0,M10.5.0"
1720 #endif /* !defined TZDEFDST */
1721 
1722 /* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX. */
1723 #define is_digit(c) ((unsigned)(c) - '0' <= 9)
1724 
1725 #define BIGGEST(a, b) (((a) > (b)) ? (a) : (b))
1726 
1727 #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
1728 
1729 
1730 
1731 /*
1732 ** INITIALIZE(x)
1733 */
1734 
1735 #ifndef GNUC_or_lint
1736 #ifdef lint
1737 #define GNUC_or_lint
1738 #endif /* defined lint */
1739 #ifndef lint
1740 #ifdef __GNUC__
1741 #define GNUC_or_lint
1742 #endif /* defined __GNUC__ */
1743 #endif /* !defined lint */
1744 #endif /* !defined GNUC_or_lint */
1745 #ifdef WIN32
1746 #define GNUC_or_lint
1747 #endif
1748 
1749 #ifndef INITIALIZE
1750 #ifdef GNUC_or_lint
1751 #define INITIALIZE(x) ((x) = 0)
1752 #endif /* defined GNUC_or_lint */
1753 #ifndef GNUC_or_lint
1754 #define INITIALIZE(x)
1755 #endif /* !defined GNUC_or_lint */
1756 #endif /* !defined INITIALIZE */
1757 
1758 
1759 #define TM_SUNDAY 0
1760 #define TM_MONDAY 1
1761 #define TM_TUESDAY 2
1762 #define TM_WEDNESDAY 3
1763 #define TM_THURSDAY 4
1764 #define TM_FRIDAY 5
1765 #define TM_SATURDAY 6
1766 
1767 #define TM_JANUARY 0
1768 #define TM_FEBRUARY 1
1769 #define TM_MARCH 2
1770 #define TM_APRIL 3
1771 #define TM_MAY 4
1772 #define TM_JUNE 5
1773 #define TM_JULY 6
1774 #define TM_AUGUST 7
1775 #define TM_SEPTEMBER 8
1776 #define TM_OCTOBER 9
1777 #define TM_NOVEMBER 10
1778 #define TM_DECEMBER 11
1779 
1780 #define TM_YEAR_BASE 1900
1781 
1782 #define EPOCH_YEAR 1970
1783 #define EPOCH_WDAY TM_THURSDAY
1784 
1785 
1786 /* **************************************************************************
1787 
1788  ************************************************************************** */
1789 
1790 static const char gmt[] = "GMT";
1791 
1792 #define CHARS_DEF BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt), (2 * (MY_TZNAME_MAX + 1)))
1793 
1794 struct rule {
1795  int r_type; /* type of rule--see below */
1796  int r_day; /* day number of rule */
1797  int r_week; /* week number of rule */
1798  int r_mon; /* month number of rule */
1799  long r_time; /* transition time of rule */
1800 };
1801 
1802 struct ttinfo { /* time type information */
1803  long tt_gmtoff; /* UTC offset in seconds */
1804  int tt_isdst; /* used to set tm_isdst */
1805  int tt_abbrind; /* abbreviation list index */
1806  int tt_ttisstd; /* TRUE if transition is std time */
1807  int tt_ttisgmt; /* TRUE if transition is UTC */
1808 };
1809 
1810 struct lsinfo { /* leap second information */
1811  time_t ls_trans; /* transition time */
1812  long ls_corr; /* correction to apply */
1813 };
1814 
1815 
1816 struct state {
1817  int leapcnt;
1818  int timecnt;
1819  int typecnt;
1820  int charcnt;
1822  unsigned char types[TZ_MAX_TIMES];
1824  char chars[ /* LINTED constant */ CHARS_DEF];
1826 };
1827 
1828 
1829 static const int mon_lengths[2][MONSPERYEAR] = {
1830  {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
1831  {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
1832 };
1833 
1834 static const int year_lengths[2] = {
1836 };
1837 
1838 
1839 /* **************************************************************************
1840 
1841  ************************************************************************** */
1842 
1843 
1844 /*
1845  Given a pointer into a time zone string, scan until a character that is not
1846  a valid character in a zone name is found. Return a pointer to that
1847  character.
1848 */
1849 
1850 static const char *getzname(register const char *strp)
1851 {
1852  register char c;
1853 
1854  while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' && c != '+')
1855  ++strp;
1856  return strp;
1857 }
1858 
1859 
1860 /*
1861  Given a pointer into a time zone string, extract a number from that string.
1862  Check that the number is within a specified range; if it is not, return
1863  NULL.
1864  Otherwise, return a pointer to the first character not part of the number.
1865 */
1866 
1867 static const char *getnum(register const char *strp, int *const nump, const int min, const int max)
1868 {
1869  register char c;
1870  register int num;
1871 
1872  if (strp == NULL || !is_digit(c = *strp))
1873  return NULL;
1874  num = 0;
1875  do {
1876  num = num * 10 + (c - '0');
1877  if (num > max)
1878  return NULL; /* illegal value */
1879  c = *++strp;
1880  } while (is_digit(c));
1881  if (num < min)
1882  return NULL; /* illegal value */
1883  *nump = num;
1884  return strp;
1885 }
1886 
1887 /*
1888  Given a pointer into a time zone string, extract a number of seconds,
1889  in hh[:mm[:ss]] form, from the string.
1890  If any error occurs, return NULL.
1891  Otherwise, return a pointer to the first character not part of the number
1892  of seconds.
1893 */
1894 
1895 static const char *getsecs(register const char *strp, long *const secsp)
1896 {
1897  int num;
1898 
1899  /*
1900  ** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
1901  ** "M10.4.6/26", which does not conform to Posix,
1902  ** but which specifies the equivalent of
1903  ** ``02:00 on the first Sunday on or after 23 Oct''.
1904  */
1905  strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
1906  if (strp == NULL)
1907  return NULL;
1908  *secsp = num * (long) SECSPERHOUR;
1909  if (*strp == ':') {
1910  ++strp;
1911  strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
1912  if (strp == NULL)
1913  return NULL;
1914  *secsp += num * SECSPERMIN;
1915  if (*strp == ':') {
1916  ++strp;
1917  /* `SECSPERMIN' allows for leap seconds. */
1918  strp = getnum(strp, &num, 0, SECSPERMIN);
1919  if (strp == NULL)
1920  return NULL;
1921  *secsp += num;
1922  }
1923  }
1924  return strp;
1925 }
1926 
1927 /*
1928  Given a pointer into a time zone string, extract an offset, in
1929  [+-]hh[:mm[:ss]] form, from the string.
1930  If any error occurs, return NULL.
1931  Otherwise, return a pointer to the first character not part of the time.
1932 */
1933 
1934 static const char *getoffset(register const char *strp, long *const offsetp)
1935 {
1936  register int neg = 0;
1937 
1938  if (*strp == '-') {
1939  neg = 1;
1940  ++strp;
1941  } else if (*strp == '+')
1942  ++strp;
1943  strp = getsecs(strp, offsetp);
1944  if (strp == NULL)
1945  return NULL; /* illegal time */
1946  if (neg)
1947  *offsetp = -*offsetp;
1948  return strp;
1949 }
1950 
1951 /*
1952  Given a pointer into a time zone string, extract a rule in the form
1953  date[/time]. See POSIX section 8 for the format of "date" and "time".
1954  If a valid rule is not found, return NULL.
1955  Otherwise, return a pointer to the first character not part of the rule.
1956 */
1957 
1958 static const char *getrule(const char *strp, register struct rule *const rulep)
1959 {
1960  if (*strp == 'J') {
1961  /*
1962  ** Julian day.
1963  */
1964  rulep->r_type = JULIAN_DAY;
1965  ++strp;
1966  strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
1967  } else if (*strp == 'M') {
1968  /*
1969  ** Month, week, day.
1970  */
1971  rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
1972  ++strp;
1973  strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
1974  if (strp == NULL)
1975  return NULL;
1976  if (*strp++ != '.')
1977  return NULL;
1978  strp = getnum(strp, &rulep->r_week, 1, 5);
1979  if (strp == NULL)
1980  return NULL;
1981  if (*strp++ != '.')
1982  return NULL;
1983  strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
1984  } else if (is_digit(*strp)) {
1985  /*
1986  ** Day of year.
1987  */
1988  rulep->r_type = DAY_OF_YEAR;
1989  strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
1990  } else
1991  return NULL; /* invalid format */
1992  if (strp == NULL)
1993  return NULL;
1994  if (*strp == '/') {
1995  /*
1996  ** Time specified.
1997  */
1998  ++strp;
1999  strp = getsecs(strp, &rulep->r_time);
2000  } else
2001  rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
2002  return strp;
2003 }
2004 
2005 
2006 /*
2007  Given the Epoch-relative time of January 1, 00:00:00 UTC, in a year, the
2008  year, a rule, and the offset from UTC at the time that rule takes effect,
2009  calculate the Epoch-relative time that rule takes effect.
2010 */
2011 
2012 static time_t transtime(const time_t janfirst, const int year, register const struct rule *const rulep, const long offset)
2013 {
2014  register int leapyear;
2015  register time_t value;
2016  register int i;
2017  int d, m1, yy0, yy1, yy2, dow;
2018 
2019  INITIALIZE(value);
2020  leapyear = isleap(year);
2021  switch (rulep->r_type) {
2022 
2023  case JULIAN_DAY:
2024  /*
2025  ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
2026  ** years.
2027  ** In non-leap years, or if the day number is 59 or less, just
2028  ** add SECSPERDAY times the day number-1 to the time of
2029  ** January 1, midnight, to get the day.
2030  */
2031  value = janfirst + (rulep->r_day - 1) * SECSPERDAY;
2032  if (leapyear && rulep->r_day >= 60)
2033  value += SECSPERDAY;
2034  break;
2035 
2036  case DAY_OF_YEAR:
2037  /*
2038  ** n - day of year.
2039  ** Just add SECSPERDAY times the day number to the time of
2040  ** January 1, midnight, to get the day.
2041  */
2042  value = janfirst + rulep->r_day * SECSPERDAY;
2043  break;
2044 
2045  case MONTH_NTH_DAY_OF_WEEK:
2046  /*
2047  ** Mm.n.d - nth "dth day" of month m.
2048  */
2049  value = janfirst;
2050  for (i = 0; i < rulep->r_mon - 1; ++i)
2051  value += mon_lengths[leapyear][i] * SECSPERDAY;
2052 
2053  /*
2054  ** Use Zeller's Congruence to get day-of-week of first day of
2055  ** month.
2056  */
2057  m1 = (rulep->r_mon + 9) % 12 + 1;
2058  yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
2059  yy1 = yy0 / 100;
2060  yy2 = yy0 % 100;
2061  dow = ((26 * m1 - 2) / 10 + 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
2062  if (dow < 0)
2063  dow += DAYSPERWEEK;
2064 
2065  /*
2066  ** "dow" is the day-of-week of the first day of the month. Get
2067  ** the day-of-month (zero-origin) of the first "dow" day of the
2068  ** month.
2069  */
2070  d = rulep->r_day - dow;
2071  if (d < 0)
2072  d += DAYSPERWEEK;
2073  for (i = 1; i < rulep->r_week; ++i) {
2074  if (d + DAYSPERWEEK >= mon_lengths[leapyear][rulep->r_mon - 1])
2075  break;
2076  d += DAYSPERWEEK;
2077  }
2078 
2079  /*
2080  ** "d" is the day-of-month (zero-origin) of the day we want.
2081  */
2082  value += d * SECSPERDAY;
2083  break;
2084  }
2085 
2086  /*
2087  ** "value" is the Epoch-relative time of 00:00:00 UTC on the day in
2088  ** question. To get the Epoch-relative time of the specified local
2089  ** time on that day, add the transition time and the current offset
2090  ** from UTC.
2091  */
2092  return value + rulep->r_time + offset;
2093 }
2094 
2095 
2096 
2097 /*
2098  Given a POSIX section 8-style TZ string, fill in the rule tables as
2099  appropriate.
2100 */
2101 
2102 static int tzparse(const char *name, register struct state *const sp, const int lastditch)
2103 {
2104  const char *stdname;
2105  const char *dstname;
2106  size_t stdlen;
2107  size_t dstlen;
2108  long stdoffset;
2109  long dstoffset;
2110  register time_t *atp;
2111  register unsigned char *typep;
2112  register char *cp;
2113 
2114 
2115  INITIALIZE(dstname);
2116  stdname = name;
2117 
2118  if (lastditch) {
2119  stdlen = strlen(name); /* length of standard zone name */
2120  name += stdlen;
2121  if (stdlen >= sizeof sp->chars)
2122  stdlen = (sizeof sp->chars) - 1;
2123  stdoffset = 0;
2124  } else {
2125  name = getzname(name);
2126  stdlen = name - stdname;
2127  if (stdlen < 3)
2128  return -1;
2129  if (*name == '\0')
2130  return -1;
2131  name = getoffset(name, &stdoffset);
2132  if (name == NULL)
2133  return -1;
2134  }
2135 
2136  sp->leapcnt = 0; /* so, we're off a little */
2137 
2138  if (*name != '\0') {
2139  dstname = name;
2140  name = getzname(name);
2141  dstlen = name - dstname; /* length of DST zone name */
2142  if (dstlen < 3)
2143  return -1;
2144  if (*name != '\0' && *name != ',' && *name != ';') {
2145  name = getoffset(name, &dstoffset);
2146  if (name == NULL)
2147  return -1;
2148  } else
2149  dstoffset = stdoffset - SECSPERHOUR;
2150 
2151  /* Go parsing the daylight saving stuff */
2152  if (*name == ',' || *name == ';') {
2153  struct rule start;
2154  struct rule end;
2155  register int year;
2156  register time_t janfirst;
2157  time_t starttime;
2158  time_t endtime;
2159 
2160  ++name;
2161  if ((name = getrule(name, &start)) == NULL)
2162  return -1;
2163  if (*name++ != ',')
2164  return -1;
2165  if ((name = getrule(name, &end)) == NULL)
2166  return -1;
2167  if (*name != '\0')
2168  return -1;
2169 
2170  sp->typecnt = 2; /* standard time and DST */
2171 
2172  /*
2173  ** Two transitions per year, from EPOCH_YEAR to 2037.
2174  */
2175  sp->timecnt = 2 * (2037 - EPOCH_YEAR + 1);
2176 
2177  if (sp->timecnt > TZ_MAX_TIMES)
2178  return -1;
2179 
2180  sp->ttis[0].tt_gmtoff = -dstoffset;
2181  sp->ttis[0].tt_isdst = 1;
2182  sp->ttis[0].tt_abbrind = (int) (stdlen + 1);
2183  sp->ttis[1].tt_gmtoff = -stdoffset;
2184  sp->ttis[1].tt_isdst = 0;
2185  sp->ttis[1].tt_abbrind = 0;
2186 
2187  atp = sp->ats;
2188  typep = sp->types;
2189  janfirst = 0;
2190 
2191  for (year = EPOCH_YEAR; year <= 2037; ++year) {
2192  starttime = transtime(janfirst, year, &start, stdoffset);
2193  endtime = transtime(janfirst, year, &end, dstoffset);
2194  if (starttime > endtime) {
2195  *atp++ = endtime;
2196  *typep++ = 1; /* DST ends */
2197  *atp++ = starttime;
2198  *typep++ = 0; /* DST begins */
2199  } else {
2200  *atp++ = starttime;
2201  *typep++ = 0; /* DST begins */
2202  *atp++ = endtime;
2203  *typep++ = 1; /* DST ends */
2204  }
2205 
2206  janfirst += year_lengths[isleap(year)] * SECSPERDAY;
2207  }
2208 
2209  } else {
2210  register long theirstdoffset;
2211  register long theirdstoffset;
2212  register long theiroffset;
2213  register int isdst;
2214  register int i;
2215  register int j;
2216 
2217  if (*name != '\0')
2218  return -1;
2219  /*
2220  Initial values of theirstdoffset and theirdstoffset.
2221  */
2222  theirstdoffset = 0;
2223  for (i = 0; i < sp->timecnt; ++i) {
2224  j = sp->types[i];
2225  if (!sp->ttis[j].tt_isdst) {
2226  theirstdoffset = -sp->ttis[j].tt_gmtoff;
2227  break;
2228  }
2229  }
2230  theirdstoffset = 0;
2231  for (i = 0; i < sp->timecnt; ++i) {
2232  j = sp->types[i];
2233  if (sp->ttis[j].tt_isdst) {
2234  theirdstoffset = -sp->ttis[j].tt_gmtoff;
2235  break;
2236  }
2237  }
2238  /*
2239  ** Initially we're assumed to be in standard time.
2240  */
2241  isdst = FALSE;
2242  theiroffset = theirstdoffset;
2243  /*
2244  ** Now juggle transition times and types
2245  ** tracking offsets as you do.
2246  */
2247  for (i = 0; i < sp->timecnt; ++i) {
2248  j = sp->types[i];
2249  sp->types[i] = (unsigned char) sp->ttis[j].tt_isdst;
2250  if (sp->ttis[j].tt_ttisgmt) {
2251  /* No adjustment to transition time */
2252  } else {
2253  /*
2254  ** If summer time is in effect, and the
2255  ** transition time was not specified as
2256  ** standard time, add the summer time
2257  ** offset to the transition time;
2258  ** otherwise, add the standard time
2259  ** offset to the transition time.
2260  */
2261  /*
2262  ** Transitions from DST to DDST
2263  ** will effectively disappear since
2264  ** POSIX provides for only one DST
2265  ** offset.
2266  */
2267  if (isdst && !sp->ttis[j].tt_ttisstd) {
2268  sp->ats[i] += dstoffset - theirdstoffset;
2269  } else {
2270  sp->ats[i] += stdoffset - theirstdoffset;
2271  }
2272  }
2273  theiroffset = -sp->ttis[j].tt_gmtoff;
2274  if (sp->ttis[j].tt_isdst)
2275  theirdstoffset = theiroffset;
2276  else
2277  theirstdoffset = theiroffset;
2278  }
2279  /*
2280  ** Finally, fill in ttis.
2281  ** ttisstd and ttisgmt need not be handled.
2282  */
2283  sp->ttis[0].tt_gmtoff = -stdoffset;
2284  sp->ttis[0].tt_isdst = FALSE;
2285  sp->ttis[0].tt_abbrind = 0;
2286  sp->ttis[1].tt_gmtoff = -dstoffset;
2287  sp->ttis[1].tt_isdst = TRUE;
2288  sp->ttis[1].tt_abbrind = (int) (stdlen + 1);
2289  sp->typecnt = 2;
2290  }
2291  } else {
2292  dstlen = 0;
2293  sp->typecnt = 1; /* only standard time */
2294  sp->timecnt = 0;
2295  sp->ttis[0].tt_gmtoff = -stdoffset;
2296  sp->ttis[0].tt_isdst = 0;
2297  sp->ttis[0].tt_abbrind = 0;
2298  }
2299 
2300  sp->charcnt = (int) (stdlen + 1);
2301  if (dstlen != 0)
2302  sp->charcnt += (int) (dstlen + 1);
2303  if ((size_t) sp->charcnt > sizeof sp->chars)
2304  return -1;
2305  cp = sp->chars;
2306  (void) strncpy(cp, stdname, stdlen);
2307  cp += stdlen;
2308  *cp++ = '\0';
2309  if (dstlen != 0) {
2310  (void) strncpy(cp, dstname, dstlen);
2311  *(cp + dstlen) = '\0';
2312  }
2313  return 0;
2314 }
2315 
2316 /* **************************************************************************
2317 
2318  ************************************************************************** */
2319 #if (_MSC_VER >= 1400) // VC8+
2320 #define switch_assert(expr) assert(expr);__analysis_assume( expr )
2321 #else
2322 #define switch_assert(expr) assert(expr)
2323 #endif
2324 
2325 static void timesub(const time_t *const timep, const long offset, register const struct state *const sp, register struct tm *const tmp)
2326 {
2327  register const struct lsinfo *lp;
2328  register long days;
2329  register time_t rem;
2330  register int y;
2331  register int yleap;
2332  register const int *ip;
2333  register long corr;
2334  register int hit;
2335  register int i;
2336 
2337  switch_assert(timep != NULL);
2338  switch_assert(sp != NULL);
2339  switch_assert(tmp != NULL);
2340 
2341  corr = 0;
2342  hit = 0;
2343  i = (sp == NULL) ? 0 : sp->leapcnt;
2344 
2345  while (--i >= 0) {
2346  lp = &sp->lsis[i];
2347  if (*timep >= lp->ls_trans) {
2348  if (*timep == lp->ls_trans) {
2349  hit = ((i == 0 && lp->ls_corr > 0) || (i > 0 && lp->ls_corr > sp->lsis[i - 1].ls_corr));
2350  if (hit)
2351  while (i > 0 && sp->lsis[i].ls_trans == sp->lsis[i - 1].ls_trans + 1 && sp->lsis[i].ls_corr == sp->lsis[i - 1].ls_corr + 1) {
2352  ++hit;
2353  --i;
2354  }
2355  }
2356  corr = lp->ls_corr;
2357  break;
2358  }
2359  }
2360  days = (long) (*timep / SECSPERDAY);
2361  rem = *timep % SECSPERDAY;
2362 
2363 
2364 #ifdef mc68k
2365  /* If this is for CPU bugs workarounds, i would remove this anyway. Who would use it on an old mc68k ? */
2366  if (*timep == 0x80000000) {
2367  /*
2368  ** A 3B1 muffs the division on the most negative number.
2369  */
2370  days = -24855;
2371  rem = -11648;
2372  }
2373 #endif
2374 
2375  rem += (offset - corr);
2376  while (rem < 0) {
2377  rem += SECSPERDAY;
2378  --days;
2379  }
2380  while (rem >= SECSPERDAY) {
2381  rem -= SECSPERDAY;
2382  ++days;
2383  }
2384  tmp->tm_hour = (int) (rem / SECSPERHOUR);
2385  rem = rem % SECSPERHOUR;
2386  tmp->tm_min = (int) (rem / SECSPERMIN);
2387 
2388  /*
2389  ** A positive leap second requires a special
2390  ** representation. This uses "... ??:59:60" et seq.
2391  */
2392  tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
2393  tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK);
2394 
2395  if (tmp->tm_wday < 0)
2396  tmp->tm_wday += DAYSPERWEEK;
2397 
2398  y = EPOCH_YEAR;
2399 
2400 #define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
2401 
2402  while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) {
2403  register int newy;
2404 
2405  newy = (int) (y + days / DAYSPERNYEAR);
2406  if (days < 0)
2407  --newy;
2408  days -= (newy - y) * DAYSPERNYEAR + LEAPS_THRU_END_OF(newy - 1) - LEAPS_THRU_END_OF(y - 1);
2409  y = newy;
2410  }
2411 
2412  tmp->tm_year = y - TM_YEAR_BASE;
2413  tmp->tm_yday = (int) days;
2414 
2415  ip = mon_lengths[yleap];
2416 
2417  for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon))
2418  days = days - (long) ip[tmp->tm_mon];
2419 
2420  tmp->tm_mday = (int) (days + 1);
2421  tmp->tm_isdst = 0;
2422 #if defined(HAVE_STRUCT_TM_TM_GMTOFF)
2423  tmp->tm_gmtoff = offset;
2424 #endif
2425 }
2426 
2427 /* **************************************************************************
2428 
2429  ************************************************************************** */
2430 
2431 static void tztime(const time_t *const timep, const char *tzstring, struct tm *const tmp)
2432 {
2433  struct state *tzptr, *sp;
2434  const time_t t = *timep;
2435  register int i;
2436  register const struct ttinfo *ttisp;
2437 
2438  if (tzstring == NULL)
2439  tzstring = gmt;
2440 
2441  tzptr = (struct state *) malloc(sizeof(struct state));
2442  sp = tzptr;
2443 
2444  if (tzptr != NULL) {
2445 
2446  memset(tzptr, 0, sizeof(struct state));
2447 
2448  (void) tzparse(tzstring, tzptr, FALSE);
2449 
2450  if (sp->timecnt == 0 || t < sp->ats[0]) {
2451  i = 0;
2452  while (sp->ttis[i].tt_isdst)
2453  if (++i >= sp->typecnt) {
2454  i = 0;
2455  break;
2456  }
2457  } else {
2458  for (i = 1; i < sp->timecnt; ++i)
2459  if (t < sp->ats[i])
2460  break;
2461  i = sp->types[i - 1]; // DST begin or DST end
2462  }
2463  ttisp = &sp->ttis[i];
2464 
2465  /*
2466  To get (wrong) behavior that's compatible with System V Release 2.0
2467  you'd replace the statement below with
2468  t += ttisp->tt_gmtoff;
2469  timesub(&t, 0L, sp, tmp);
2470  */
2471  if (tmp != NULL) { /* Just a check not to assert */
2472  timesub(&t, ttisp->tt_gmtoff, sp, tmp);
2473  tmp->tm_isdst = ttisp->tt_isdst;
2474 #if defined(HAVE_STRUCT_TM_TM_ZONE)
2475  tmp->tm_zone = &sp->chars[ttisp->tt_abbrind];
2476 #endif
2477  }
2478 
2479  free(tzptr);
2480  }
2481 
2482 }
2483 
2484 /* For Emacs:
2485  * Local Variables:
2486  * mode:c
2487  * indent-tabs-mode:t
2488  * tab-width:4
2489  * c-basic-offset:4
2490  * End:
2491  * For VIM:
2492  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
2493  */
#define check_roll()
Definition: switch_time.c:749
int32_t use_cond_yield
Definition: switch_time.c:104
switch_time_t switch_micro_time_now(void)
Get the current epoch time in microseconds.
Definition: switch_time.c:310
void switch_xml_free(_In_opt_ switch_xml_t xml)
frees the memory allocated for an switch_xml structure
void switch_time_sync(void)
Definition: switch_time.c:589
#define JULIAN_DAY
Definition: switch_time.c:1689
static switch_status_t timer_sync(switch_timer_t *timer)
Definition: switch_time.c:791
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core's master pool.
Definition: switch_core.h:631
static switch_status_t timer_init(switch_timer_t *timer)
Definition: switch_time.c:679
static switch_status_t timer_step(switch_timer_t *timer)
Definition: switch_time.c:756
switch_status_t switch_thread_cond_create(switch_thread_cond_t **cond, switch_memory_pool_t *pool)
Definition: switch_apr.c:350
int32_t STARTED
Definition: switch_time.c:103
SWITCH_MODULE_DEFINITION(CORE_SOFTTIMER_MODULE, softtimer_load, softtimer_shutdown, softtimer_runtime)
switch_status_t switch_event_bind_removable(const char *id, switch_event_types_t event, const char *subclass_name, switch_event_callback_t callback, void *user_data, switch_event_node_t **node)
Bind an event callback to a specific event.
#define SWITCH_CHANNEL_LOG
switch_time_t initiated
switch_status_t switch_mutex_trylock(switch_mutex_t *lock)
Definition: switch_apr.c:295
switch_status_t switch_core_hash_destroy(_Inout_ switch_hash_t **hash)
Destroy an existing hash table.
int tt_ttisstd
Definition: switch_time.c:1806
void * switch_core_hash_find(_In_ switch_hash_t *hash, _In_z_ const char *key)
Retrieve data from a given hash.
static switch_time_t time_now(int64_t offset)
Definition: switch_time.c:520
const char * switch_xml_attr(_In_opt_ switch_xml_t xml, _In_opt_z_ const char *attr)
returns the value of the requested tag attribute, or NULL if not found
static void tm2switchtime(struct tm *tm, switch_time_exp_t *xt)
Definition: switch_time.c:1324
#define switch_core_hash_init(_hash)
Definition: switch_core.h:1390
void switch_os_yield(void)
Definition: switch_time.c:141
static timer_matrix_t TIMER_MATRIX[MAX_ELEMENTS+1]
Definition: switch_time.c:137
long r_time
Definition: switch_time.c:1799
#define MAX_ELEMENTS
Definition: switch_time.c:52
void switch_time_set_nanosleep(switch_bool_t enable)
Definition: switch_time.c:365
int32_t timer_affinity
static const char * getoffset(register const char *strp, long *const offsetp)
Definition: switch_time.c:1934
time_t ats[TZ_MAX_TIMES]
Definition: switch_time.c:1821
void switch_sleep(switch_interval_time_t t)
Definition: switch_time.c:620
uint32_t timer_count
Definition: switch_time.c:106
#define HOURSPERDAY
Definition: switch_time.c:1681
int charcnt
Definition: switch_time.c:1820
#define SECSPERMIN
Definition: switch_time.c:1679
switch_bool_t
Definition: switch_types.h:405
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:729
static const char gmt[]
Definition: switch_time.c:1790
int leapcnt
Definition: switch_time.c:1817
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:640
switch_memory_pool_t * pool
Representation of an event.
Definition: switch_event.h:80
#define TZ_MAX_TIMES
Definition: switch_time.c:1642
#define TZ_MAX_TYPES
Definition: switch_time.c:1648
void switch_cond_yield(switch_interval_time_t t)
Definition: switch_time.c:657
SWITCH_MODULE_SHUTDOWN_FUNCTION(softtimer_shutdown)
Definition: switch_time.c:1567
static int TFD
Definition: switch_time.c:80
static switch_timezones_list_t TIMEZONES_LIST
Definition: switch_time.c:1358
#define MAX_TICK
Definition: switch_time.c:50
SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
Definition: switch_time.c:1019
A representation of an XML tree.
Definition: switch_xml.h:76
static switch_memory_pool_t * module_pool
Definition: switch_time.c:99
switch_mutex_t * throttle_mutex
switch_status_t switch_thread_cond_wait(switch_thread_cond_t *cond, switch_mutex_t *mutex)
Definition: switch_apr.c:355
A table of functions that a timer module implements.
A node to store binded events.
Definition: switch_event.c:46
switch_status_t switch_strftime_nocheck(char *s, switch_size_t *retsize, switch_size_t max, const char *format, switch_time_exp_t *tm)
Definition: switch_apr.c:179
void switch_time_set_timerfd(int enable)
Definition: switch_time.c:347
static const int year_lengths[2]
Definition: switch_time.c:1834
Abstract handler to a timer module.
int r_mon
Definition: switch_time.c:1798
struct switch_runtime runtime
Definition: switch_core.c:64
uint32_t microseconds_per_tick
static switch_interval_time_t average_time(switch_interval_time_t t, int reps)
Definition: switch_time.c:190
struct apr_thread_cond_t switch_thread_cond_t
Definition: switch_apr.h:463
static switch_status_t timer_destroy(switch_timer_t *timer)
Definition: switch_time.c:925
#define EPOCH_WDAY
Definition: switch_time.c:1783
switch_status_t switch_core_thread_set_cpu_affinity(int cpu)
Definition: switch_core.c:1723
#define zstr(x)
Definition: switch_utils.h:281
static switch_status_t timer_next(switch_timer_t *timer)
Definition: switch_time.c:821
int r_week
Definition: switch_time.c:1797
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
SWITCH_MODULE_LOAD_FUNCTION(softtimer_load)
Definition: switch_time.c:1495
struct lsinfo lsis[TZ_MAX_LEAPS]
Definition: switch_time.c:1825
#define switch_clear_flag(obj, flag)
Clear a flag on an arbitrary object while locked.
Definition: switch_utils.h:655
void switch_micro_sleep(switch_interval_time_t t)
Definition: switch_time.c:615
#define SWITCH_MUTEX_NESTED
Definition: switch_apr.h:318
static int MONO
Definition: switch_time.c:63
int64_t switch_time_t
Definition: switch_apr.h:188
int32_t sessions_peak_fivemin
if((uint32_t)(unpack->cur-unpack->buf) > unpack->buflen)
switch_xml_t next
Definition: switch_xml.h:88
switch_status_t(* timer_next)(switch_timer_t *)
static void timesub(const time_t *const timep, const long offset, register const struct state *const sp, register struct tm *const tmp)
Definition: switch_time.c:2325
void switch_time_set_matrix(switch_bool_t enable)
Definition: switch_time.c:359
static time_t transtime(const time_t janfirst, const int year, register const struct rule *const rulep, const long offset)
Definition: switch_time.c:2012
switch_bool_t switch_get_system_idle_time(switch_profile_timer_t *p, double *idle_percentage)
provides the percentage of idle system time
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
switch_memory_pool_t * memory_pool
switch_status_t(* timer_init)(switch_timer_t *)
switch_memory_pool_t * pool
Definition: switch_time.c:1354
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:682
switch_status_t(* timer_sync)(switch_timer_t *)
switch_size_t start
Definition: switch_time.c:121
struct apr_thread_rwlock_t switch_thread_rwlock_t
Definition: switch_apr.h:436
uint32_t roll
Definition: switch_time.c:130
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:270
#define MINSPERHOUR
Definition: switch_time.c:1680
static int tzparse(const char *name, register struct state *const sp, const int lastditch)
Definition: switch_time.c:2102
#define UINT32_MAX
Definition: switch_time.c:47
switch_status_t switch_strftime_tz(const char *tz, const char *format, char *date, size_t len, switch_time_t thetime)
Definition: switch_time.c:1458
uintptr_t switch_size_t
static const int mon_lengths[2][MONSPERYEAR]
Definition: switch_time.c:1829
int r_day
Definition: switch_time.c:1796
static int OFFSET
Definition: switch_time.c:84
switch_mutex_t * session_hash_mutex
void switch_cond_next(void)
Definition: switch_time.c:638
static struct @7 globals
switch_size_t reference
Definition: switch_time.c:120
int64_t switch_interval_time_t
Definition: switch_apr.h:191
#define zstr_buf(s)
Definition: switch_utils.h:285
#define TRUE
Definition: switch_time.c:1626
int r_type
Definition: switch_time.c:1795
static int COND
Definition: switch_time.c:86
char chars[CHARS_DEF]
Definition: switch_time.c:1824
long ls_corr
Definition: switch_time.c:1812
static void tztime(const time_t *const timep, const char *tzstring, struct tm *const tmp)
Definition: switch_time.c:2431
#define INITIALIZE(x)
Definition: switch_time.c:1754
void switch_delete_profile_timer(switch_profile_timer_t **p)
Deletes profile timer.
long tt_gmtoff
Definition: switch_time.c:1803
uint32_t count
Definition: switch_time.c:129
static switch_status_t timer_check(switch_timer_t *timer, switch_bool_t step)
Definition: switch_time.c:884
struct ttinfo ttis[TZ_MAX_TYPES]
Definition: switch_time.c:1823
unsigned char types[TZ_MAX_TIMES]
Definition: switch_time.c:1822
#define switch_assert(expr)
Definition: switch_time.c:2322
#define isleap(y)
Definition: switch_time.c:1727
switch_profile_timer_t * switch_new_profile_timer(void)
create a new profile timer
static switch_event_node_t * NODE
Definition: switch_time.c:1359
const char * switch_lookup_timezone(const char *tz_name)
Definition: switch_time.c:1361
void switch_load_timezones(switch_bool_t reload)
Definition: switch_time.c:1376
switch_time_t timestamp
void switch_time_set_monotonic(switch_bool_t enable)
Definition: switch_time.c:330
struct apr_thread_mutex_t switch_mutex_t
Definition: switch_apr.h:314
uint32_t ready
Definition: switch_time.c:123
switch_status_t
Common return values.
switch_xml_t switch_xml_open_cfg(_In_z_ const char *file_path, _Out_ switch_xml_t *node, _In_opt_ switch_event_t *params)
open a config in the core registry
#define is_digit(c)
Definition: switch_time.c:1723
static const char * getzname(register const char *strp)
Definition: switch_time.c:1850
switch_loadable_module_interface_t * switch_loadable_module_create_module_interface(switch_memory_pool_t *pool, const char *name)
switch_thread_cond_t * cond
Definition: switch_time.c:132
#define TZ_MAX_LEAPS
Definition: switch_time.c:1667
#define switch_core_hash_insert(_h, _k, _d)
Definition: switch_core.h:1410
#define SECSPERHOUR
Definition: switch_time.c:1685
int timecnt
Definition: switch_time.c:1818
switch_hash_t * hash
Definition: switch_time.c:1355
static switch_status_t timer_generic_sync(switch_timer_t *timer)
Definition: switch_time.c:381
void switch_time_calibrate_clock(void)
Definition: switch_time.c:207
Main Library Header.
static const char * getsecs(register const char *strp, long *const secsp)
Definition: switch_time.c:1895
struct switch_session_manager session_manager
#define SECSPERDAY
Definition: switch_time.c:1686
uint32_t tipping_point
#define LEAPS_THRU_END_OF(y)
int32_t sps_peak_fivemin
switch_mutex_t * mutex
Definition: switch_time.c:131
#define SWITCH_DECLARE(type)
switch_status_t(* timer_check)(switch_timer_t *, switch_bool_t)
static int NANO
Definition: switch_time.c:81
#define DAYSPERWEEK
Definition: switch_time.c:1682
#define MONTH_NTH_DAY_OF_WEEK
Definition: switch_time.c:1691
switch_time_t switch_mono_micro_time_now(void)
Definition: switch_time.c:315
switch_xml_t switch_xml_child(_In_ switch_xml_t xml, _In_z_ const char *name)
returns the first child tag (one level deeper) with the given name or NULL \ if not found ...
static const char * getnum(register const char *strp, int *const nump, const int min, const int max)
Definition: switch_time.c:1867
void switch_time_set_use_system_time(switch_bool_t enable)
Definition: switch_time.c:341
#define TM_YEAR_BASE
Definition: switch_time.c:1780
void switch_time_set_cond_yield(switch_bool_t enable)
Definition: switch_time.c:372
time_t switch_epoch_time_now(time_t *t)
Get the current epoch time.
Definition: switch_time.c:321
#define CHARS_DEF
Definition: switch_time.c:1792
uint64_t tick
Definition: switch_time.c:128
switch_status_t(* timer_destroy)(switch_timer_t *)
#define MONSPERYEAR
Definition: switch_time.c:1687
struct apr_pool_t switch_memory_pool_t
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
int32_t RUNNING
Definition: switch_time.c:102
int tt_abbrind
Definition: switch_time.c:1805
switch_status_t(* timer_step)(switch_timer_t *)
static switch_time_t last_time
Definition: switch_time.c:587
while(unpack->bits_cur<=SWITCH_BITS_PER_BYTE)
#define calc_step()
Definition: switch_time.c:206
uint32_t roll
Definition: switch_time.c:122
#define EPOCH_YEAR
Definition: switch_time.c:1782
static void do_sleep(switch_interval_time_t t)
Definition: switch_time.c:150
switch_status_t switch_thread_cond_broadcast(switch_thread_cond_t *cond)
Definition: switch_apr.c:376
time_t ls_trans
Definition: switch_time.c:1811
static void event_handler(switch_event_t *event)
Definition: switch_time.c:1418
switch_status_t switch_time_exp_tz_name(const char *tz, switch_time_exp_t *tm, switch_time_t thetime)
Definition: switch_time.c:1427
static int SYSTEM_TIME
Definition: switch_time.c:67
switch_thread_rwlock_t * rwlock
Definition: switch_time.c:133
static void win32_init_timers(void)
Definition: switch_time.c:970
switch_time_t switch_time_now(void)
Definition: switch_apr.c:302
int tt_isdst
Definition: switch_time.c:1804
switch_mutex_t * mutex
Definition: switch_time.c:105
int typecnt
Definition: switch_time.c:1819
int tt_ttisgmt
Definition: switch_time.c:1807
#define FALSE
Definition: switch_time.c:1630
#define DAYSPERNYEAR
Definition: switch_time.c:1683
#define DAYSPERLYEAR
Definition: switch_time.c:1684
memset(buf, 0, buflen)
static int MATRIX
Definition: switch_time.c:88
#define DAY_OF_YEAR
Definition: switch_time.c:1690
switch_profile_timer_t * profile_timer
switch_time_t reference
void * switch_loadable_module_create_interface(switch_loadable_module_interface_t *mod, switch_module_interface_name_t iname)
switch_time_t switch_time_ref(void)
Definition: switch_time.c:576
static const char * getrule(const char *strp, register struct rule *const rulep)
Definition: switch_time.c:1958
switch_status_t switch_event_unbind(switch_event_node_t **node)
Unbind a bound event consumer.