Commit c0378663 authored by Seblu's avatar Seblu
Browse files

Fix mutex error

parent dfa8d9fc
Loading
Loading
Loading
Loading
+23 −15
Original line number Diff line number Diff line
@@ -106,14 +106,14 @@ void Connection::connect(const char *addr, int port) {
  }

  // take read and write mutex
  pthread_mutex_lock(&r_mutex_);
  pthread_mutex_lock(&w_mutex_);
  pthread_mutex_lock(&r_mutex_);

  // retrieve remote host info
  struct hostent *h = gethostbyname(addr);
  if (h == 0) {
    pthread_mutex_unlock(&w_mutex_);
    pthread_mutex_unlock(&r_mutex_);
    pthread_mutex_unlock(&w_mutex_);
    pthread_mutex_unlock(&c_mutex_);
    throw Error(ERR_NET, (string) "Unable to resolve: " + addr  + ": " + hstrerror(h_errno));
  }
@@ -121,8 +121,8 @@ void Connection::connect(const char *addr, int port) {
  // create socket
  try { socket_(); }
  catch (...) {
    pthread_mutex_unlock(&w_mutex_);
    pthread_mutex_unlock(&r_mutex_);
    pthread_mutex_unlock(&w_mutex_);
    pthread_mutex_unlock(&c_mutex_);
    throw;
  }
@@ -138,8 +138,8 @@ void Connection::connect(const char *addr, int port) {
  if (::connect(socket_fd_, (struct sockaddr *) &daddr, sizeof daddr) == -1) {
    int errno__ = errno;
    disconnect_();
    pthread_mutex_unlock(&w_mutex_);
    pthread_mutex_unlock(&r_mutex_);
    pthread_mutex_unlock(&w_mutex_);
    pthread_mutex_unlock(&c_mutex_);
    throw Error(ERR_NET, (string) "Unable to connect to " + addr  + ": " + strerror(errno__));
  }
@@ -152,14 +152,14 @@ void Connection::connect(const char *addr, int port) {
    setremoteport_();
  }
  catch (...) {
    pthread_mutex_unlock(&w_mutex_);
    pthread_mutex_unlock(&r_mutex_);
    pthread_mutex_unlock(&w_mutex_);
    pthread_mutex_unlock(&c_mutex_);
    throw;
  }

  pthread_mutex_unlock(&w_mutex_);
  pthread_mutex_unlock(&r_mutex_);
  pthread_mutex_unlock(&w_mutex_);
  pthread_mutex_unlock(&c_mutex_);
}

@@ -243,26 +243,34 @@ void Connection::listen(int port, int max) {
 * @return null on error, else a new connection
 */
Connection *Connection::accept() {
  // keep the socket fd
  // accept is a read/write op
  pthread_mutex_lock(&c_mutex_);
  pthread_mutex_lock(&r_mutex_);
  pthread_mutex_lock(&w_mutex_);

  // get the socket fd
  int socket_fd = socket_fd_;
  pthread_mutex_unlock(&c_mutex_);

  // test socket validity
  if (socket_fd < 0)
  if (socket_fd < 0) {
    pthread_mutex_unlock(&r_mutex_);
    pthread_mutex_unlock(&w_mutex_);
    throw Error(ERR_NET, "No connection established but trying to accept");
  }

  struct sockaddr_in r_addr;
  socklen_t r_sin_size = sizeof r_addr;
  int r_fd;

  // accept is a read/write operation
  pthread_mutex_lock(&r_mutex_);
  pthread_mutex_lock(&w_mutex_);

  if ((r_fd = ::accept(socket_fd, (struct sockaddr *) &r_addr, &r_sin_size)) == -1) {
    int errno__ = errno;
    pthread_mutex_lock(&c_mutex_);
    disconnect_();
    pthread_mutex_unlock(&r_mutex_);
    pthread_mutex_unlock(&w_mutex_);
    pthread_mutex_unlock(&c_mutex_);
    throw Error(ERR_NET, (string) "accept: " + strerror(errno));
    throw Error(ERR_NET, (string) "accept: " + strerror(errno__));
  }

  pthread_mutex_unlock(&r_mutex_);
@@ -299,8 +307,8 @@ void Connection::send(const char* buf, size_t len) {
    pthread_mutex_lock(&r_mutex_);
    disconnect_();
    pthread_mutex_unlock(&r_mutex_);
    pthread_mutex_unlock(&c_mutex_);
    pthread_mutex_unlock(&w_mutex_);
    pthread_mutex_unlock(&c_mutex_);
    if (errno__ == ECONNRESET || errno__ == EPIPE)
      throw Error(ERR_NET, "Connection reset by peer");
    else
@@ -354,9 +362,9 @@ string Connection::recvln() {
      pthread_mutex_lock(&c_mutex_);
      pthread_mutex_lock(&w_mutex_);
      disconnect_();
      pthread_mutex_unlock(&w_mutex_);
      pthread_mutex_unlock(&r_mutex_);
      pthread_mutex_unlock(&c_mutex_);
      pthread_mutex_unlock(&r_mutex_);

      *local_buf = 0;