]> git.sur5r.net Git - bacula/bacula/commitdiff
Use light weight non-recursive locking on jcr chain.
authorKern Sibbald <kern@sibbald.com>
Thu, 26 May 2005 20:44:05 +0000 (20:44 +0000)
committerKern Sibbald <kern@sibbald.com>
Thu, 26 May 2005 20:44:05 +0000 (20:44 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@2091 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/kes-1.37
bacula/src/dird/dird.c
bacula/src/jcr.h
bacula/src/lib/jcr.c
bacula/src/lib/protos.h
bacula/src/lib/res.c

index b5a483f514ca07bd76be53b3bfa978514a4b8c0d..5db4c08a9fa0a37a812c92710455f6c0ef266d5c 100644 (file)
@@ -5,6 +5,7 @@ General:
 
 Changes to 1.37.20:
 26May05
+- Use light weight non-recursive locking on jcr chain.
 - Make JCR a class and implement inc_use_count() and
   dec_use_count() methods that ensure that the jcr is
   locked when inc/dec the use count.
index b8ee906569dfc0824dc49858e97823c4657aac04..e0ff0aa264da07c7dac504c544a0d8aa7eee4240 100644 (file)
    Copyright (C) 2000-2005 Kern Sibbald
 
    This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2 of
-   the License.
+   modify it under the terms of the GNU General Public License
+   version 2 as ammended with additional clauses defined in the
+   file LICENSE in the main source directory.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public
-   License along with this program; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-   MA 02111-1307, USA.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+   the file LICENSE for additional details.
 
  */
 
@@ -241,8 +236,6 @@ int main (int argc, char *argv[])
 
    init_job_server(director->MaxConcurrentJobs);
 
-// init_device_resources();
-
    Dmsg0(200, "wait for next job\n");
    /* Main loop -- call scheduler to get next job to run */
    while ((jcr = wait_for_next_job(runjob))) {
@@ -334,13 +327,13 @@ static void reload_job_end_cb(JCR *jcr, void *ctx)
    int reload_id = (int)((long int)ctx);
    Dmsg3(100, "reload job_end JobId=%d table=%d cnt=%d\n", jcr->JobId,
       reload_id, reload_table[reload_id].job_count);
-   lock_jcr_chain();
+   lock_jobs();
    LockRes();
    if (--reload_table[reload_id].job_count <= 0) {
       free_saved_resources(reload_id);
    }
    UnlockRes();
-   unlock_jcr_chain();
+   unlock_jobs();
 }
 
 static int find_free_reload_table_entry()
@@ -392,7 +385,7 @@ void reload_config(int sig)
    sigaddset(&set, SIGHUP);
    sigprocmask(SIG_BLOCK, &set, NULL);
 
-   lock_jcr_chain();
+   lock_jobs();
    LockRes();
 
    table = find_free_reload_table_entry();
@@ -452,7 +445,7 @@ void reload_config(int sig)
 
 bail_out:
    UnlockRes();
-   unlock_jcr_chain();
+   unlock_jobs();
    sigprocmask(SIG_UNBLOCK, &set, NULL);
    signal(SIGHUP, reload_config);
    already_here = false;
index ba7fd9cea4f20b033c082e25c2aba747c4666f4d..45faa3ef0188cff5b9ee71eba1e0cd3bf63a5b5f 100644 (file)
@@ -316,16 +316,6 @@ extern JCR *get_jcr_by_full_name(char *Job);
 extern JCR *get_next_jcr(JCR *jcr);
 extern void set_jcr_job_status(JCR *jcr, int JobStatus);
 
-#ifdef TRACE_JCR_CHAIN
-extern void b_lock_jcr_chain(const char *filen, int line);
-extern void b_unlock_jcr_chain(const char *filen, int line);
-#define lock_jcr_chain() b_lock_jcr_chain(__FILE__, __LINE__);
-#define unlock_jcr_chain() b_unlock_jcr_chain(__FILE__, __LINE__);
-#else
-extern void lock_jcr_chain();
-extern void unlock_jcr_chain();
-#endif
-
 #ifdef DEBUG
 extern void b_free_jcr(const char *file, int line, JCR *jcr);
 #define free_jcr(jcr) b_free_jcr(__FILE__, __LINE__, (jcr))
index 964d5c3e2759c04060882b8e7b201568a7168d2f..d0ca12e3332f3ae492ffb473dd08d1b2008ee379 100755 (executable)
@@ -45,27 +45,49 @@ extern time_t watchdog_time;
 
 /* Forward referenced functions */
 extern "C" void timeout_handler(int sig);
-
 static void jcr_timeout_check(watchdog_t *self);
+#ifdef TRACE_JCR_CHAIN
+static void b_lock_jcr_chain(const char *filen, int line);
+static void b_unlock_jcr_chain(const char *filen, int line);
+#define lock_jcr_chain() b_lock_jcr_chain(__FILE__, __LINE__);
+#define unlock_jcr_chain() b_unlock_jcr_chain(__FILE__, __LINE__);
+#else
+static void lock_jcr_chain();
+static void unlock_jcr_chain();
+#endif
+
 
 int num_jobs_run;
 dlist *last_jobs = NULL;
 const int max_last_jobs = 10;
  
 static dlist *jcrs = NULL;            /* JCR chain */
-static brwlock_t lock;                /* lock for last jobs and JCR chain */
+//static brwlock_t lock;                /* lock for last jobs and JCR chain */
+static pthread_mutex_t jcr_lock = PTHREAD_MUTEX_INITIALIZER;
+
+static pthread_mutex_t job_start_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+void lock_jobs()
+{
+   P(job_start_mutex);
+}
+
+void unlock_jobs()
+{
+   V(job_start_mutex);
+}
 
 void init_last_jobs_list()
 {
-   int errstat;
+// int errstat;
    JCR *jcr;
    struct s_last_job *job_entry = NULL;
    if (!last_jobs) {
       last_jobs = New(dlist(job_entry, &job_entry->link));
-      if ((errstat=rwl_init(&lock)) != 0) {
-         Emsg1(M_ABORT, 0, _("Unable to initialize jcr_chain lock. ERR=%s\n"),
-               strerror(errstat));
-      }
+//    if ((errstat=rwl_init(&lock)) != 0) {
+//       Emsg1(M_ABORT, 0, _("Unable to initialize jcr_chain lock. ERR=%s\n"),
+//             strerror(errstat));
+//    }
    }
    if (!jcrs) {
       jcrs = New(dlist(jcr, &jcr->link));
@@ -82,7 +104,7 @@ void term_last_jobs_list()
       }
       delete last_jobs;
       last_jobs = NULL;
-      rwl_destroy(&lock);
+//    rwl_destroy(&lock);
       delete jcrs;
    }
 }
@@ -228,12 +250,20 @@ JCR *new_jcr(int size, JCR_free_HANDLER *daemon_free_jcr)
    sigfillset(&sigtimer.sa_mask);
    sigaction(TIMEOUT_SIGNAL, &sigtimer, NULL);
 
+   /*
+    * Locking jobs is a global lock that is needed
+    * so that the Director can stop new jobs from being
+    * added to the jcr chain while it processes a new
+    * conf file and does the job_end_push().
+    */
+   lock_jobs();
    lock_jcr_chain();
    if (!jcrs) {
       jcrs = New(dlist(jcr, &jcr->link));
    }
    jcrs->append(jcr);
    unlock_jcr_chain();
+   unlock_jobs();
 
    return jcr;
 }
@@ -516,40 +546,42 @@ static int lock_count = 0;
  * Lock the chain
  */
 #ifdef TRACE_JCR_CHAIN
-void b_lock_jcr_chain(const char *fname, int line)
+static void b_lock_jcr_chain(const char *fname, int line)
 #else
-void lock_jcr_chain()
+static void lock_jcr_chain()
 #endif
 {
-   int errstat;
+// int errstat;
 #ifdef TRACE_JCR_CHAIN
    Dmsg3(3400, "Lock jcr chain %d from %s:%d\n", ++lock_count,
       fname, line);
 #endif
-   if ((errstat=rwl_writelock(&lock)) != 0) {
-      Emsg1(M_ABORT, 0, "rwl_writelock failure. ERR=%s\n",
-           strerror(errstat));
-   }
+// if ((errstat=rwl_writelock(&lock)) != 0) {
+//    Emsg1(M_ABORT, 0, "rwl_writelock failure. ERR=%s\n",
+//         strerror(errstat));
+// }
+   P(jcr_lock);
 }
 
 /*
  * Unlock the chain
  */
 #ifdef TRACE_JCR_CHAIN
-void b_unlock_jcr_chain(const char *fname, int line)
+static void b_unlock_jcr_chain(const char *fname, int line)
 #else
-void unlock_jcr_chain()
+static void unlock_jcr_chain()
 #endif
 {
-   int errstat;
+// int errstat;
 #ifdef TRACE_JCR_CHAIN
    Dmsg3(3400, "Unlock jcr chain %d from %s:%d\n", lock_count--,
       fname, line);
 #endif
-   if ((errstat=rwl_writeunlock(&lock)) != 0) {
-      Emsg1(M_ABORT, 0, "rwl_writeunlock failure. ERR=%s\n",
-           strerror(errstat));
-   }
+// if ((errstat=rwl_writeunlock(&lock)) != 0) {
+//    Emsg1(M_ABORT, 0, "rwl_writeunlock failure. ERR=%s\n",
+//         strerror(errstat));
+// }
+   V(jcr_lock);
 }
 
 
index 942ac1a4eb5154e5acd99de0edc8d74194b93456..6519503fed7de2f6c7c5de94f800515c91fa83c0 100644 (file)
@@ -141,6 +141,8 @@ void read_last_jobs_list(int fd, uint64_t addr);
 uint64_t write_last_jobs_list(int fd, uint64_t addr);
 void write_state_file(char *dir, const char *progname, int port);
 void job_end_push(JCR *jcr, void job_end_cb(JCR *jcr,void *), void *ctx);
+void lock_jobs();
+void unlock_jobs();
 
 
 /* lex.c */
index 04dab6bfe7e4bcda2c9415213894c03bbb5ac174..e3065284f205f6f3409f741f1cb8490d9f2e7ed3 100644 (file)
@@ -2,32 +2,25 @@
  *  This file handles locking and seaching resources
  *
  *     Kern Sibbald, January MM
- *      Split from parse_conf.c April MMV
+ *       Split from parse_conf.c April MMV
  *
  *   Version $Id$
  */
-
 /*
    Copyright (C) 2000-2005 Kern Sibbald
 
    This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2 of
-   the License, or (at your option) any later version.
+   modify it under the terms of the GNU General Public License
+   version 2 as ammended with additional clauses defined in the
+   file LICENSE in the main source directory.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public
-   License along with this program; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-   MA 02111-1307, USA.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+   the file LICENSE for additional details.
 
  */
 
-
 #include "bacula.h"
 
 extern int debug_level;
@@ -47,14 +40,13 @@ extern RES **res_head;
 extern "C" CURES res_all;
 extern "C" int res_all_size;
 #else
-extern CURES res_all;
+extern  CURES res_all;
 extern int res_all_size;
 #endif
 
 
-brwlock_t res_lock;                  /* resource lock */
-static int res_locked = 0;           /* set when resource chains locked -- for debug */
-
+brwlock_t res_lock;                   /* resource lock */
+static int res_locked = 0;            /* set when resource chains locked -- for debug */
 
 
 /* #define TRACE_RES */
@@ -64,15 +56,15 @@ void b_LockRes(const char *file, int line)
    int errstat;
 #ifdef TRACE_RES
    Pmsg4(000, "LockRes  locked=%d w_active=%d at %s:%d\n", 
-        res_locked, res_lock.w_active, file, line);
+         res_locked, res_lock.w_active, file, line);
     if (res_locked) {
        Pmsg2(000, "LockRes writerid=%d myid=%d\n", res_lock.writer_id,
-         pthread_self());
+          pthread_self());
      }
 #endif
    if ((errstat=rwl_writelock(&res_lock)) != 0) {
       Emsg3(M_ABORT, 0, "rwl_writelock failure at %s:%d:  ERR=%s\n",
-          file, line, strerror(errstat));
+           file, line, strerror(errstat));
    }
    res_locked++;
 }
@@ -82,12 +74,12 @@ void b_UnlockRes(const char *file, int line)
    int errstat;
    if ((errstat=rwl_writeunlock(&res_lock)) != 0) {
       Emsg3(M_ABORT, 0, "rwl_writeunlock failure at %s:%d:. ERR=%s\n",
-          file, line, strerror(errstat));
+           file, line, strerror(errstat));
    }
    res_locked--;
 #ifdef TRACE_RES
    Pmsg4(000, "UnLockRes locked=%d wactive=%d at %s:%d\n", 
-        res_locked, res_lock.w_active, file, line);
+         res_locked, res_lock.w_active, file, line);
 #endif
 }
 
@@ -104,7 +96,7 @@ GetResWithName(int rcode, char *name)
    res = res_head[rindex];
    while (res) {
       if (strcmp(res->name, name) == 0) {
-        break;
+         break;
       }
       res = res->next;
    }
@@ -124,10 +116,6 @@ GetNextRes(int rcode, RES *res)
    RES *nres;
    int rindex = rcode - r_first;
 
-
-//   if (!res_locked) {
-//      Emsg0(M_ABORT, 0, "Resource chain not locked.\n");
-//   }
    if (res == NULL) {
       nres = res_head[rindex];
    } else {