[asterisk-commits] anthonyl: branch anthonyl/7852-patchtest r43689 - in /team/anthonyl/7852-patc...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Tue Sep 26 12:50:31 MST 2006


Author: anthonyl
Date: Tue Sep 26 14:50:30 2006
New Revision: 43689

URL: http://svn.digium.com/view/asterisk?rev=43689&view=rev
Log:
patched

Modified:
    team/anthonyl/7852-patchtest/doc/asterisk-conf.txt
    team/anthonyl/7852-patchtest/include/asterisk/app.h
    team/anthonyl/7852-patchtest/main/app.c
    team/anthonyl/7852-patchtest/main/asterisk.c

Modified: team/anthonyl/7852-patchtest/doc/asterisk-conf.txt
URL: http://svn.digium.com/view/asterisk/team/anthonyl/7852-patchtest/doc/asterisk-conf.txt?rev=43689&r1=43688&r2=43689&view=diff
==============================================================================
--- team/anthonyl/7852-patchtest/doc/asterisk-conf.txt (original)
+++ team/anthonyl/7852-patchtest/doc/asterisk-conf.txt Tue Sep 26 14:50:30 2006
@@ -69,6 +69,10 @@
 	       	       				; when off, sound files are searched as <path>/<lang>/<file>
 						; when on, sound files are search as <lang>/<path>/<file>
 						; (only affects relative paths for sound files)
+lockmode = lockfile | flock			; Locking mode for voicemail
+						;   lockfile: default, for normal use
+						;   flock: for where the lockfile locking method doesn't work, eg. on SMB/CIFS mounts
+
 
 [files]
 ; Changing the following lines may compromise your security

Modified: team/anthonyl/7852-patchtest/include/asterisk/app.h
URL: http://svn.digium.com/view/asterisk/team/anthonyl/7852-patchtest/include/asterisk/app.h?rev=43689&r1=43688&r2=43689&view=diff
==============================================================================
--- team/anthonyl/7852-patchtest/include/asterisk/app.h (original)
+++ team/anthonyl/7852-patchtest/include/asterisk/app.h Tue Sep 26 14:50:30 2006
@@ -190,6 +190,18 @@
 	AST_LOCK_FAILURE = -3,
 };
 
+/* Type of locking to use in ast_lock_path / ast_unlock_path */
+enum AST_LOCK_TYPE {
+	AST_LOCK_TYPE_LOCKFILE = 0,
+	AST_LOCK_TYPE_FLOCK = 1,
+};
+
+/*!
+ * \brief Set the type of locks used by ast_lock_path()
+ * \param type the locking type to use
+ */
+void ast_set_lock_type(enum AST_LOCK_TYPE type);
+
 /*!
  * \brief Lock a filesystem path.
  * \param path the path to be locked

Modified: team/anthonyl/7852-patchtest/main/app.c
URL: http://svn.digium.com/view/asterisk/team/anthonyl/7852-patchtest/main/app.c?rev=43689&r1=43688&r2=43689&view=diff
==============================================================================
--- team/anthonyl/7852-patchtest/main/app.c (original)
+++ team/anthonyl/7852-patchtest/main/app.c Tue Sep 26 14:50:30 2006
@@ -37,6 +37,7 @@
 #include <dirent.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/file.h>
 #include <regex.h>
 
 #include "asterisk/channel.h"
@@ -52,6 +53,8 @@
 
 #define MAX_OTHER_FORMATS 10
 
+/* The lock type used by ast_lock_path() / ast_unlock_path() */
+static enum AST_LOCK_TYPE ast_lock_type = AST_LOCK_TYPE_LOCKFILE;
 
 /* !
 This function presents a dialtone and reads an extension into 'collect' 
@@ -898,7 +901,7 @@
 	return argc;
 }
 
-enum AST_LOCK_RESULT ast_lock_path(const char *path)
+static enum AST_LOCK_RESULT ast_lock_path_lockfile(const char *path)
 {
 	char *s;
 	char *fs;
@@ -936,7 +939,7 @@
 	}
 }
 
-int ast_unlock_path(const char *path)
+static int ast_unlock_path_lockfile(const char *path)
 {
 	char *s;
 	int res;
@@ -954,6 +957,137 @@
 		ast_log(LOG_DEBUG, "Unlocked path '%s'\n", path);
 
 	return res;
+}
+
+struct path_lock {
+	AST_LIST_ENTRY(path_lock) le;
+	int fd;
+	char *path;
+};
+
+static AST_LIST_HEAD_STATIC(path_lock_list, path_lock);
+
+static void path_lock_destroy(struct path_lock *obj)
+{
+	if (obj->fd >= 0)
+		close(obj->fd);
+	if (obj->path)
+		free(obj->path);
+	free(obj);
+}
+
+static enum AST_LOCK_RESULT ast_lock_path_flock(const char *path)
+{
+	char *fs;
+	int res;
+	int fd;
+	time_t start;
+	struct path_lock *pl;
+
+	fs = alloca(strlen(path) + 20);
+
+	if (!fs) {
+		ast_log(LOG_WARNING, "Out of memory!\n");
+		return AST_LOCK_FAILURE;
+	}
+
+	snprintf(fs, strlen(path) + 19, "%s/lock", path);
+	fd = open(fs, O_WRONLY | O_CREAT, 0600);
+	if (fd < 0) {
+		fprintf(stderr, "Unable to create lock file '%s': %s\n", fs, strerror(errno));
+		return AST_LOCK_PATH_NOT_FOUND;
+	}
+	pl = malloc(sizeof(*pl));
+	if (!pl) {
+		ast_log(LOG_WARNING, "Out of memory!\n");
+		return AST_LOCK_FAILURE;
+		close(fd);
+	}
+	memset(pl, 0, sizeof(*pl));
+	pl->fd = fd;
+	pl->path = strdup(path);
+
+	time(&start);
+	while (((res = flock(pl->fd, LOCK_EX | LOCK_NB)) < 0) && (errno == EWOULDBLOCK) && (time(NULL) - start < 5))
+		usleep(1000);
+	if (res) {
+		ast_log(LOG_WARNING, "Failed to lock path '%s': %s\n", path, strerror(errno));
+		path_lock_destroy(pl);
+		return AST_LOCK_TIMEOUT;
+	}
+	AST_LIST_LOCK(&path_lock_list);
+	AST_LIST_INSERT_TAIL(&path_lock_list, pl, le);
+	AST_LIST_UNLOCK(&path_lock_list);
+
+	ast_log(LOG_DEBUG, "Locked path '%s'\n", path);
+
+	return AST_LOCK_SUCCESS;
+}
+
+static int ast_unlock_path_flock(const char *path)
+{
+	char *s;
+	struct path_lock *p;
+
+	s = alloca(strlen(path) + 20);
+	if (!s)
+		return -1;
+	snprintf(s, strlen(path) + 19, "%s/lock", path);
+
+	AST_LIST_LOCK(&path_lock_list);
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&path_lock_list, p, le) {
+		if (!strcmp(p->path, path)) {
+			AST_LIST_REMOVE_CURRENT(&path_lock_list, le);
+			break;
+		}
+	}
+	AST_LIST_TRAVERSE_SAFE_END;
+	AST_LIST_UNLOCK(&path_lock_list);
+
+	if (p) {
+		path_lock_destroy(p);
+		ast_log(LOG_DEBUG, "Unlocked path '%s'\n", path);
+	} else
+		ast_log(LOG_DEBUG, "Failed to unlock path '%s': lock not found\n", path);
+
+	return 0;
+}
+
+void ast_set_lock_type(enum AST_LOCK_TYPE type)
+{
+	ast_lock_type = type;
+}
+
+enum AST_LOCK_RESULT ast_lock_path(const char *path)
+{
+	enum AST_LOCK_RESULT r = AST_LOCK_FAILURE;
+
+	switch (ast_lock_type) {
+		case AST_LOCK_TYPE_LOCKFILE:
+			r = ast_lock_path_lockfile(path);
+			break;
+		case AST_LOCK_TYPE_FLOCK:
+			r = ast_lock_path_flock(path);
+			break;
+	}
+
+	return r;
+}
+
+int ast_unlock_path(const char *path)
+{
+	int r = 0;
+
+	switch (ast_lock_type) {
+		case AST_LOCK_TYPE_LOCKFILE:
+			r = ast_unlock_path_lockfile(path);
+			break;
+		case AST_LOCK_TYPE_FLOCK:
+			r = ast_unlock_path_flock(path);
+			break;
+	}
+
+	return r;
 }
 
 int ast_record_review(struct ast_channel *chan, const char *playfile, const char *recordfile, int maxtime, const char *fmt, int *duration, const char *path) 

Modified: team/anthonyl/7852-patchtest/main/asterisk.c
URL: http://svn.digium.com/view/asterisk/team/anthonyl/7852-patchtest/main/asterisk.c?rev=43689&r1=43688&r2=43689&view=diff
==============================================================================
--- team/anthonyl/7852-patchtest/main/asterisk.c (original)
+++ team/anthonyl/7852-patchtest/main/asterisk.c Tue Sep 26 14:50:30 2006
@@ -2317,6 +2317,14 @@
 			ast_copy_string(ast_config_AST_SYSTEM_NAME, v->value, sizeof(ast_config_AST_SYSTEM_NAME));
 		} else if (!strcasecmp(v->name, "languageprefix")) {
 			ast_language_is_prefix = ast_true(v->value);
+		} else if (!strcasecmp(v->name, "lockmode")) {
+			if (!strcasecmp(v->value, "lockfile")) {
+				ast_set_lock_type(AST_LOCK_TYPE_LOCKFILE);
+			} else if (!strcasecmp(v->value, "flock")) {
+				ast_set_lock_type(AST_LOCK_TYPE_FLOCK);
+			} else {
+				ast_set_lock_type(AST_LOCK_TYPE_LOCKFILE);
+			}
 		}
 	}
 	ast_config_destroy(cfg);



More information about the asterisk-commits mailing list