extern time_t watchdog_time;
/* Forward referenced functions */
-static void timeout_handler(int sig);
+extern "C" void timeout_handler(int sig);
+
static void jcr_timeout_check(watchdog_t *self);
int num_jobs_run;
dlist *last_jobs = NULL;
-static const int max_last_jobs = 10;
+const int max_last_jobs = 10;
static JCR *jobs = NULL; /* pointer to JCR chain */
static brwlock_t lock; /* lock for last jobs and JCR chain */
int errstat;
struct s_last_job *job_entry = NULL;
if (!last_jobs) {
- last_jobs = new dlist(job_entry, &job_entry->link);
+ 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));
uint32_t num;
Dmsg1(100, "read_last_jobs seek to %d\n", (int)addr);
- if (addr == 0 || lseek(fd, addr, SEEK_SET) < 0) {
+ if (addr == 0 || lseek(fd, (off_t)addr, SEEK_SET) < 0) {
return;
}
if (read(fd, &num, sizeof(num)) != sizeof(num)) {
uint32_t num;
Dmsg1(100, "write_last_jobs seek to %d\n", (int)addr);
- if (lseek(fd, addr, SEEK_SET) < 0) {
+ if (lseek(fd, (off_t)addr, SEEK_SET) < 0) {
return 0;
}
if (last_jobs) {
/*
* Push a subroutine address into the job end callback stack
*/
-void job_end_push(JCR *jcr, void job_end_cb(JCR *jcr))
+void job_end_push(JCR *jcr, void job_end_cb(JCR *jcr,void *), void *ctx)
{
- jcr->job_end_push.prepend((void *)job_end_cb);
+ jcr->job_end_push.append((void *)job_end_cb);
+ jcr->job_end_push.append(ctx);
}
/* Pop each job_end subroutine and call it */
static void job_end_pop(JCR *jcr)
{
- void (*job_end_cb)(JCR *jcr);
- for (int i=0; i<jcr->job_end_push.size(); i++) {
- job_end_cb = (void (*)(JCR *))jcr->job_end_push.get(i);
- job_end_cb(jcr);
+ void (*job_end_cb)(JCR *jcr, void *ctx);
+ void *ctx;
+ for (int i=jcr->job_end_push.size()-1; i > 0; ) {
+ ctx = jcr->job_end_push.get(i--);
+ job_end_cb = (void (*)(JCR *,void *))jcr->job_end_push.get(i--);
+ job_end_cb(jcr, ctx);
}
}
Dmsg0(400, "Enter new_jcr\n");
jcr = (JCR *)malloc(size);
memset(jcr, 0, size);
- jcr->msg_queue = new dlist(item, &item->link);
+ jcr->msg_queue = New(dlist(item, &item->link));
jcr->job_end_push.init(1, false);
jcr->sched_time = time(NULL);
jcr->daemon_free_jcr = daemon_free_jcr; /* plug daemon free routine */
case JT_RESTORE:
case JT_ADMIN:
num_jobs_run++;
+ last_job.Errors = jcr->Errors;
last_job.JobType = jcr->JobType;
last_job.JobId = jcr->JobId;
last_job.VolSessionId = jcr->VolSessionId;
#endif
+ dequeue_messages(jcr);
lock_jcr_chain();
jcr->use_count--; /* decrement use count */
if (jcr->use_count < 0) {
Dmsg2(400, "free_jcr 0x%x use_count=%d\n", jcr, jcr->use_count);
return;
}
- dequeue_messages(jcr);
- remove_jcr(jcr);
+ remove_jcr(jcr); /* remove Jcr from chain */
+ unlock_jcr_chain();
+
job_end_pop(jcr); /* pop and call hooked routines */
Dmsg1(400, "End job=%d\n", jcr->JobId);
if (jcr->daemon_free_jcr) {
jcr->daemon_free_jcr(jcr); /* call daemon free routine */
}
-
free_common_jcr(jcr);
-
close_msg(NULL); /* flush any daemon messages */
- unlock_jcr_chain();
Dmsg0(400, "Exit free_jcr\n");
}
}
}
+#ifdef TRACE_JCR_CHAIN
+static int lock_count = 0;
+#endif
+
/*
* Lock the chain
*/
+#ifdef TRACE_JCR_CHAIN
+void b_lock_jcr_chain(const char *fname, int line)
+#else
void lock_jcr_chain()
+#endif
{
int errstat;
+#ifdef TRACE_JCR_CHAIN
+ Dmsg3(000, "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));
/*
* Unlock the chain
*/
+#ifdef TRACE_JCR_CHAIN
+void b_unlock_jcr_chain(const char *fname, int line)
+#else
void unlock_jcr_chain()
+#endif
{
int errstat;
+#ifdef TRACE_JCR_CHAIN
+ Dmsg3(000, "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));
/*
* Timeout signal comes here
*/
-static void timeout_handler(int sig)
+extern "C" void timeout_handler(int sig)
{
return; /* thus interrupting the function */
}