]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
use file locks to keep multiple concurrent copies of freeswitch from running at the...
authorMichael Jerris <mike@jerris.com>
Sat, 8 Dec 2007 03:41:00 +0000 (03:41 +0000)
committerMichael Jerris <mike@jerris.com>
Sat, 8 Dec 2007 03:41:00 +0000 (03:41 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@6575 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/include/switch_apr.h
src/switch.c
src/switch_apr.c

index e7e639b3d6563f9d996d468454b08620dfcdfff7..2239f12149ed57811adee8f3a8b9b1b692f71677 100644 (file)
@@ -644,6 +644,29 @@ SWITCH_DECLARE(switch_status_t) switch_queue_trypush(switch_queue_t * queue, voi
 #define SWITCH_FPROT_FILE_SOURCE_PERMS 0x1000  /**< Copy source file's permissions */
 /** @} */
 
+/* File lock types/flags */
+/**
+ * @defgroup switch_file_lock_types File Lock Types
+ * @{
+ */
+
+#define SWITCH_FLOCK_SHARED        1       /**< Shared lock. More than one process
+                                           or thread can hold a shared lock
+                                           at any given time. Essentially,
+                                           this is a "read lock", preventing
+                                           writers from establishing an
+                                           exclusive lock. */
+#define SWITCH_FLOCK_EXCLUSIVE     2       /**< Exclusive lock. Only one process
+                                           may hold an exclusive lock at any
+                                           given time. This is analogous to
+                                           a "write lock". */
+
+#define SWITCH_FLOCK_TYPEMASK      0x000F  /**< mask to extract lock type */
+#define SWITCH_FLOCK_NONBLOCK      0x0010  /**< do not block while acquiring the
+                                           file lock */
+
+ /** @} */
+
 /**
  * @defgroup switch_file_open_flags File Open Flags/Routines
  * @ingroup switch_file_io
@@ -711,6 +734,8 @@ SWITCH_DECLARE(switch_status_t) switch_file_seek(switch_file_t * thefile, switch
  */
 SWITCH_DECLARE(switch_status_t) switch_file_close(switch_file_t * thefile);
 
+SWITCH_DECLARE(switch_status_t) switch_file_lock(switch_file_t * thefile, int type);
+
 /**
  * Delete the specified file.
  * @param path The full path to the file (using / on all systems)
index 9028749c2e7a4a8195d864e6edcb6a582bfba3dd..10068a1bb19c5cd9582f49c4b01ca728f236dec5 100644 (file)
@@ -38,6 +38,7 @@
 #endif
 
 #include <switch.h>
+#include "private/switch_core_pvt.h"
 
 /* pid filename: Stores the process id of the freeswitch process */
 #define PIDFILE "freeswitch.pid"
@@ -198,6 +199,8 @@ void WINAPI service_main(DWORD numArgs, char **args)
 int main(int argc, char *argv[])
 {
        char pid_path[256] = "";        /* full path to the pid file */
+       char pid_buffer[32] = "";       /* pid string */
+       switch_size_t pid_len;
        const char *err = NULL;         /* error value for return from freeswitch initialization */
 #ifndef WIN32
        int nf = 0;                                     /* TRUE if we are running in nofork mode */
@@ -205,7 +208,6 @@ int main(int argc, char *argv[])
        char *runas_group = NULL;
 #endif
        int nc = 0;                                     /* TRUE if we are running in noconsole mode */
-       FILE *f;                                        /* file handle to the pid file */
        pid_t pid = 0;
        int x;
        int die = 0;
@@ -215,6 +217,9 @@ int main(int argc, char *argv[])
        int high_prio = 0;
        switch_core_flag_t flags = SCF_USE_SQL;
        int status;
+    switch_file_t *fd;
+       switch_memory_pool_t *pool = NULL;
+
 
 #ifdef WIN32
        SERVICE_TABLE_ENTRY dispatchTable[] = {
@@ -417,25 +422,46 @@ int main(int argc, char *argv[])
        }
 #endif
 
-       if (switch_core_init_and_modload(flags, nc ? SWITCH_FALSE : SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
-               fprintf(stderr, "Cannot Initilize [%s]\n", err);
+       if (apr_initialize() != SWITCH_STATUS_SUCCESS) {
+               fprintf(stderr, "FATAL ERROR! Could not initilize APR\n");
                return 255;
        }
 
+       switch_core_set_globals();
+
+       pid = getpid();
+
        snprintf(pid_path, sizeof(pid_path), "%s%s%s", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR, pfile);
-       if ((f = fopen(pid_path, "w")) == 0) {
+       snprintf(pid_buffer, sizeof(pid_buffer), "%d", pid);
+       pid_len = strlen(pid_buffer);
+
+       apr_pool_create(&pool, NULL);
+    if (switch_file_open(&fd,
+                                               pid_path,
+                                               SWITCH_FOPEN_WRITE | SWITCH_FOPEN_CREATE,
+                                               SWITCH_FPROT_UREAD | SWITCH_FPROT_UWRITE,
+                                               pool) != SWITCH_STATUS_SUCCESS) {
                fprintf(stderr, "Cannot open pid file %s.\n", pid_path);
                return 255;
        }
 
-       fprintf(f, "%d", pid = getpid());
-       fflush(f);
+       if (switch_file_lock(fd, SWITCH_FLOCK_EXCLUSIVE | SWITCH_FLOCK_NONBLOCK) != SWITCH_STATUS_SUCCESS) {
+               fprintf(stderr, "Cannot lock pid file %s.\n", pid_path);
+               return 255;
+       }
+
+       switch_file_write(fd, pid_buffer, &pid_len);
+
+       if (switch_core_init_and_modload(flags, nc ? SWITCH_FALSE : SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) {
+               fprintf(stderr, "Cannot Initilize [%s]\n", err);
+               return 255;
+       }
 
        switch_core_runtime_loop(nc);
 
        status = switch_core_destroy();
 
-       fclose(f);
+       switch_file_close(fd);
        unlink(pid_path);
 
        return status;
index e5beea84dd6c5e34ce210109a5ba5824d630f1dc..33003f5e136fd1072ce1536e6588a71ddb548b8a 100644 (file)
@@ -328,6 +328,11 @@ SWITCH_DECLARE(switch_status_t) switch_file_close(switch_file_t * thefile)
        return apr_file_close(thefile);
 }
 
+SWITCH_DECLARE(switch_status_t) switch_file_lock(switch_file_t * thefile, int type)
+{
+       return apr_file_lock(thefile, type);
+}
+
 SWITCH_DECLARE(switch_status_t) switch_file_rename(const char *from_path, const char *to_path, switch_memory_pool_t *pool)
 {
        return apr_file_rename(from_path, to_path, pool);