summaryrefslogtreecommitdiff
path: root/pbx
diff options
context:
space:
mode:
authorIvan Poddubny <ivan.poddubny@gmail.com>2015-05-11 12:07:31 +0000
committerIvan Poddubny <ivan.poddubny@gmail.com>2015-05-11 20:32:25 +0000
commitd5864a358c0adf813ed0122eb32006b43fe688de (patch)
treef509a2790b2f78b94776c01b72c916a0d553f3ac /pbx
parent4dbd4021c91a6a612746ed5e116021e270bc6ff5 (diff)
pbx/pbx_spool: Fix issue when call files were executed too early
pbx_spool used to delete/move the call file upon successful outgoing call completion, but did not delete it from in-memory list of files (dirlist, used only when compiled with inotify/kqueue support). That resulted in an extra attempt to process that filename after retrytime seconds. Then, if a new file with the same name appears that is scheduled in future further than the completed one plus its retrytime, then it gets executed earlier than expected. This patch fixes remove_from_queue function to also remove the entry from the dirlist. ASTERISK-17069 #close Reported by: Jeremy Kister ASTERISK-24442 #close Reported by: tootai Change-Id: If9ec9b88073661ce485d6b008fd0b2612e49a28b
Diffstat (limited to 'pbx')
-rw-r--r--pbx/pbx_spool.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/pbx/pbx_spool.c b/pbx/pbx_spool.c
index 119ab08b8..4228be9b0 100644
--- a/pbx/pbx_spool.c
+++ b/pbx/pbx_spool.c
@@ -102,6 +102,14 @@ struct outgoing {
};
#if defined(HAVE_INOTIFY) || defined(HAVE_KQUEUE)
+struct direntry {
+ AST_LIST_ENTRY(direntry) list;
+ time_t mtime;
+ char name[0];
+};
+
+static AST_LIST_HEAD_STATIC(dirlist, direntry);
+
static void queue_file(const char *filename, time_t when);
#endif
@@ -323,6 +331,10 @@ static int remove_from_queue(struct outgoing *o, const char *status)
char newfn[256];
const char *bname;
+#if defined(HAVE_INOTIFY) || defined(HAVE_KQUEUE)
+ struct direntry *cur;
+#endif
+
if (!ast_test_flag(&o->options, SPOOL_FLAG_ALWAYS_DELETE)) {
struct stat current_file_status;
@@ -333,6 +345,19 @@ static int remove_from_queue(struct outgoing *o, const char *status)
}
}
+#if defined(HAVE_INOTIFY) || defined(HAVE_KQUEUE)
+ AST_LIST_LOCK(&dirlist);
+ AST_LIST_TRAVERSE_SAFE_BEGIN(&dirlist, cur, list) {
+ if (!strcmp(cur->name, o->fn)) {
+ AST_LIST_REMOVE_CURRENT(list);
+ ast_free(cur);
+ break;
+ }
+ }
+ AST_LIST_TRAVERSE_SAFE_END;
+ AST_LIST_UNLOCK(&dirlist);
+#endif
+
if (!ast_test_flag(&o->options, SPOOL_FLAG_ARCHIVE)) {
unlink(o->fn);
return 0;
@@ -486,14 +511,6 @@ static int scan_service(const char *fn, time_t now)
return 0;
}
-#if defined(HAVE_INOTIFY) || defined(HAVE_KQUEUE)
-struct direntry {
- AST_LIST_ENTRY(direntry) list;
- time_t mtime;
- char name[0];
-};
-
-static AST_LIST_HEAD_STATIC(dirlist, direntry);
#if defined(HAVE_INOTIFY)
/* Only one thread is accessing this list, so no lock is necessary */
@@ -501,6 +518,8 @@ static AST_LIST_HEAD_NOLOCK_STATIC(createlist, direntry);
static AST_LIST_HEAD_NOLOCK_STATIC(openlist, direntry);
#endif
+#if defined(HAVE_INOTIFY) || defined(HAVE_KQUEUE)
+
static void queue_file(const char *filename, time_t when)
{
struct stat st;