]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/lib/bsock.c
ebl use tokyocabinet by default instead of htable
[bacula/bacula] / bacula / src / lib / bsock.c
index 32a163acc896a0bcedfc96d32883520debdbac4b..cc26cc58645f16e672d1b19ce6071ac0de0f524a 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2007-2007 Free Software Foundation Europe e.V.
+   Copyright (C) 2007-2008 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
@@ -85,6 +85,12 @@ void BSOCK::free_bsock()
    destroy();
 }
 
+void BSOCK::free_tls()
+{
+   free_tls_connection(this->tls);
+   this->tls = NULL;
+}   
+
 /*
  * Try to connect to host for max_retry_time at retry_time intervals.
  *   Note, you must have called the constructor prior to calling
@@ -104,7 +110,7 @@ bool BSOCK::connect(JCR * jcr, int retry_interval, utime_t max_retry_time,
 
    /* Try to trap out of OS call when time expires */
    if (max_retry_time) {
-      tid = start_thread_timer(pthread_self(), (uint32_t)max_retry_time);
+      tid = start_thread_timer(jcr, pthread_self(), (uint32_t)max_retry_time);
    }
    
    for (i = 0; !open(jcr, name, host, service, port, heart_beat, &fatal);
@@ -251,7 +257,34 @@ bool BSOCK::open(JCR *jcr, const char *name, char *host, char *service,
    return true;
 }
 
+/*
+ * Force read/write to use locking
+ */
+bool BSOCK::set_locking()
+{
+   int stat;
+   if (m_use_locking) {
+      return true;                      /* already set */
+   }
+   if ((stat = pthread_mutex_init(&m_mutex, NULL)) != 0) {
+      berrno be;
+      Jmsg(m_jcr, M_FATAL, 0, _("Could not init bsock mutex. ERR=%s\n"),
+         be.bstrerror(stat));
+      return false;
+   }
+   m_use_locking = true;
+   return true;
+}
 
+void BSOCK::clear_locking()
+{
+   if (!m_use_locking) {
+      return;
+   }
+   m_use_locking = false;
+   pthread_mutex_destroy(&m_mutex);
+   return;
+}
 
 /*
  * Send a message over the network. The send consists of
@@ -266,10 +299,12 @@ bool BSOCK::send()
    int32_t rc;
    int32_t pktsiz;
    int32_t *hdr;
+   bool ok = true;
 
    if (errors || is_terminated() || msglen > 1000000) {
       return false;
    }
+   if (m_use_locking) P(m_mutex);
    /* Compute total packet length */
    if (msglen <= 0) {
       pktsiz = sizeof(pktsiz);               /* signal, no data */
@@ -310,9 +345,10 @@ bool BSOCK::send()
                _("Wrote %d bytes to %s:%s:%d, but only %d accepted.\n"),
                msglen, m_who, m_host, m_port, rc);
       }
-      return false;
+      ok = false;
    }
-   return true;
+   if (m_use_locking) V(m_mutex);
+   return ok;
 }
 
 /*
@@ -374,6 +410,7 @@ int32_t BSOCK::recv()
       return BNET_HARDEOF;
    }
 
+   if (m_use_locking) P(m_mutex);
    read_seqno++;            /* bump sequence number */
    timer_start = watchdog_time;  /* set start wait time */
    clear_timed_out();
@@ -387,7 +424,8 @@ int32_t BSOCK::recv()
          b_errno = errno;
       }
       errors++;
-      return BNET_HARDEOF;         /* assume hard EOF received */
+      nbytes = BNET_HARDEOF;        /* assume hard EOF received */
+      goto get_out;
    }
    timer_start = 0;         /* clear timer */
    if (nbytes != sizeof(int32_t)) {
@@ -395,16 +433,18 @@ int32_t BSOCK::recv()
       b_errno = EIO;
       Qmsg5(m_jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"),
             sizeof(int32_t), nbytes, m_who, m_host, m_port);
-      return BNET_ERROR;
+      nbytes = BNET_ERROR;
+      goto get_out;
    }
 
    pktsiz = ntohl(pktsiz);         /* decode no. of bytes that follow */
 
    if (pktsiz == 0) {              /* No data transferred */
-      timer_start = 0;      /* clear timer */
+      timer_start = 0;             /* clear timer */
       in_msg_no++;
       msglen = 0;
-      return 0;                    /* zero bytes read */
+      nbytes = 0;                  /* zero bytes read */
+      goto get_out;
    }
 
    /* If signal or packet size too big */
@@ -418,10 +458,11 @@ int32_t BSOCK::recv()
       if (pktsiz == BNET_TERMINATE) {
          set_terminated();
       }
-      timer_start = 0;      /* clear timer */
+      timer_start = 0;                /* clear timer */
       b_errno = ENODATA;
-      msglen = pktsiz;      /* signal code */
-      return BNET_SIGNAL;          /* signal */
+      msglen = pktsiz;                /* signal code */
+      nbytes =  BNET_SIGNAL;          /* signal */
+      goto get_out;
    }
 
    /* Make sure the buffer is big enough + one byte for EOS */
@@ -442,7 +483,8 @@ int32_t BSOCK::recv()
       errors++;
       Qmsg4(m_jcr, M_ERROR, 0, _("Read error from %s:%s:%d: ERR=%s\n"),
             m_who, m_host, m_port, this->bstrerror());
-      return BNET_ERROR;
+      nbytes = BNET_ERROR;
+      goto get_out;
    }
    timer_start = 0;         /* clear timer */
    in_msg_no++;
@@ -452,7 +494,8 @@ int32_t BSOCK::recv()
       errors++;
       Qmsg5(m_jcr, M_ERROR, 0, _("Read expected %d got %d from %s:%s:%d\n"),
             pktsiz, nbytes, m_who, m_host, m_port);
-      return BNET_ERROR;
+      nbytes = BNET_ERROR;
+      goto get_out;
    }
    /* always add a zero by to properly terminate any
     * string that was send to us. Note, we ensured above that the
@@ -460,6 +503,9 @@ int32_t BSOCK::recv()
     */
    msg[nbytes] = 0; /* terminate in case it is a string */
    sm_check(__FILE__, __LINE__, false);
+
+get_out:
+   if (m_use_locking) V(m_mutex);
    return nbytes;                  /* return actual length of message */
 }
 
@@ -776,6 +822,7 @@ int BSOCK::wait_data_intr(int sec)
       return -1;                /* error return */
    default:
       b_errno = 0;
+      break;
    }
    return 1;
 }
@@ -793,6 +840,9 @@ void BSOCK::close()
    BSOCK *bsock = this;
    BSOCK *next;
 
+   if (!m_duped) {
+      clear_locking();
+   }
    for (; bsock; bsock = next) {
       next = bsock->m_next;           /* get possible pointer to next before destoryed */
       if (!bsock->m_duped) {