From: Kern Sibbald Date: Thu, 26 May 2005 20:44:05 +0000 (+0000) Subject: Use light weight non-recursive locking on jcr chain. X-Git-Tag: Release-1.38.0~409 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=712d0570d0d180d42af3cec8b81403ae524e9291;p=bacula%2Fbacula Use light weight non-recursive locking on jcr chain. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@2091 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/kes-1.37 b/bacula/kes-1.37 index b5a483f514..5db4c08a9f 100644 --- a/bacula/kes-1.37 +++ b/bacula/kes-1.37 @@ -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. diff --git a/bacula/src/dird/dird.c b/bacula/src/dird/dird.c index b8ee906569..e0ff0aa264 100644 --- a/bacula/src/dird/dird.c +++ b/bacula/src/dird/dird.c @@ -10,19 +10,14 @@ 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; diff --git a/bacula/src/jcr.h b/bacula/src/jcr.h index ba7fd9cea4..45faa3ef01 100644 --- a/bacula/src/jcr.h +++ b/bacula/src/jcr.h @@ -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)) diff --git a/bacula/src/lib/jcr.c b/bacula/src/lib/jcr.c index 964d5c3e27..d0ca12e333 100755 --- a/bacula/src/lib/jcr.c +++ b/bacula/src/lib/jcr.c @@ -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); } diff --git a/bacula/src/lib/protos.h b/bacula/src/lib/protos.h index 942ac1a4eb..6519503fed 100644 --- a/bacula/src/lib/protos.h +++ b/bacula/src/lib/protos.h @@ -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 */ diff --git a/bacula/src/lib/res.c b/bacula/src/lib/res.c index 04dab6bfe7..e3065284f2 100644 --- a/bacula/src/lib/res.c +++ b/bacula/src/lib/res.c @@ -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 {