Fix test_time on Mac OS X (and other platforms without inotify)
authorTilghman Lesher <tilghman@meg.abyt.es>
Tue, 16 Mar 2010 19:34:01 +0000 (19:34 +0000)
committerTilghman Lesher <tilghman@meg.abyt.es>
Tue, 16 Mar 2010 19:34:01 +0000 (19:34 +0000)
Reviewboard: https://reviewboard.asterisk.org/r/554/

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@252846 65c4cc65-6c06-0410-ace0-fbb531ad65f3

include/asterisk/localtime.h
main/stdtime/localtime.c
tests/test_time.c

index d9f98f8..8858c43 100644 (file)
@@ -78,4 +78,11 @@ int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm
  */
 char *ast_strptime(const char *s, const char *format, struct ast_tm *tm);
 
+/*!\brief Wakeup localtime monitor thread
+ * For use in testing.  Normally, the failsafe monitor thread waits 60 seconds
+ * between checks to verify whether a timezone file has changed.  This routine
+ * forces the monitor thread to wakeup immediately and check the timezone files.
+ */
+void ast_localtime_wakeup_monitor(void);
+
 #endif /* _ASTERISK_LOCALTIME_H */
index 925ef02..eb9a2b1 100644 (file)
@@ -239,12 +239,11 @@ static void *inotify_daemon(void *data)
        } buf;
        ssize_t res;
        struct state *cur;
-       struct timespec ten_seconds = { 10, 0 };
 
        inotify_fd = inotify_init();
 
        ast_mutex_lock(&initialization_lock);
-       ast_cond_signal(&initialization);
+       ast_cond_broadcast(&initialization);
        ast_mutex_unlock(&initialization_lock);
 
        if (inotify_fd < 0) {
@@ -261,8 +260,7 @@ static void *inotify_daemon(void *data)
                        break;
                } else if (res < 0) {
                        if (errno == EINTR || errno == EAGAIN) {
-                               /* If read fails, then wait a bit, then continue */
-                               nanosleep(&ten_seconds, NULL);
+                               /* If read fails, try again */
                                continue;
                        }
                        /* Sanity check -- this should never happen, either */
@@ -278,6 +276,7 @@ static void *inotify_daemon(void *data)
                        }
                }
                AST_LIST_TRAVERSE_SAFE_END
+               ast_cond_broadcast(&initialization);
                AST_LIST_UNLOCK(&zonelist);
        }
        close(inotify_fd);
@@ -326,7 +325,7 @@ static void *notify_daemon(void *data)
        struct timespec sixty_seconds = { 60, 0 };
 
        ast_mutex_lock(&initialization_lock);
-       ast_cond_signal(&initialization);
+       ast_cond_broadcast(&initialization);
        ast_mutex_unlock(&initialization_lock);
 
        for (;/*ever*/;) {
@@ -347,12 +346,14 @@ static void *notify_daemon(void *data)
                        stat(name, &st);
                        lstat(name, &lst);
                        if (st.st_mtime > cur->mtime[0] || lst.st_mtime > cur->mtime[1]) {
+                               ast_log(LOG_NOTICE, "Removing cached TZ entry '%s' because underlying file changed.\n", name);
                                AST_LIST_REMOVE_CURRENT(list);
                                ast_free(cur);
                                continue;
                        }
                }
                AST_LIST_TRAVERSE_SAFE_END
+               ast_cond_broadcast(&initialization);
                AST_LIST_UNLOCK(&zonelist);
        }
        inotify_thread = AST_PTHREADT_NULL;
@@ -381,6 +382,16 @@ static void add_notify(struct state *sp, const char *path)
 }
 #endif
 
+void ast_localtime_wakeup_monitor(void)
+{
+       if (inotify_thread != AST_PTHREADT_NULL) {
+               AST_LIST_LOCK(&zonelist);
+               pthread_kill(inotify_thread, SIGURG);
+               ast_cond_wait(&initialization, &(&zonelist)->lock);
+               AST_LIST_UNLOCK(&zonelist);
+       }
+}
+
 /*! \note
 ** Section 4.12.3 of X3.159-1989 requires that
 **     Except for the strftime function, these functions [asctime,
index b4933e8..4116131 100644 (file)
@@ -90,19 +90,26 @@ AST_TEST_DEFINE(test_timezone_watch)
                        int system_res;
                        snprintf(syscmd, sizeof(syscmd), "%s " TZDIR "/%s %s", type == 0 ? "cp" : "ln -sf", zones[i], tzfile);
                        if ((system_res = system(syscmd))) {
-                               ast_log(LOG_WARNING, "system() returned non-zero: %d\n", system_res);
+                               ast_log(LOG_WARNING, "system(%s) returned non-zero: %d\n", syscmd, system_res);
                        }
+                       ast_localtime_wakeup_monitor();
                        ast_localtime(&tv, &atm[i], tzfile);
                        if (i != 0) {
                                if (atm[i].tm_hour == atm[i - 1].tm_hour) {
                                        res = AST_TEST_FAIL;
-                                       ast_test_status_update(test, "Failed %s test\n", type == 0 ? "deletion" : "symlink");
+                                       ast_test_status_update(test, "Failed %s test: %d(%s) = %d(%s)\n", type == 0 ? "deletion" : "symlink", atm[i].tm_hour, zones[i], atm[i-1].tm_hour, zones[i-1]);
                                }
                        }
+
+                       /* stat(2) only has resolution to 1 second - must wait, or the mtime is the same */
+                       usleep(1100000);
                }
        }
 
        snprintf(syscmd, sizeof(syscmd), "rm -rf %s", tmpdir);
+       if (system(syscmd)) {
+               ast_log(LOG_WARNING, "system(%s) returned non-zero.\n", syscmd);
+       }
 
        /* Restore SIGCHLD handler */
        ast_unreplace_sigchld();