Example #1
0
static void *nogvl_close(void *ptr) {
  mysql_client_wrapper *wrapper;
  wrapper = ptr;
  if (wrapper->connected) {
    wrapper->active_thread = Qnil;
    wrapper->connected = 0;
#ifndef _WIN32
    /* Invalidate the socket before calling mysql_close(). This prevents
     * mysql_close() from sending a mysql-QUIT or from calling shutdown() on
     * the socket. The difference is that invalidate_fd will drop this
     * process's reference to the socket only, while a QUIT or shutdown()
     * would render the underlying connection unusable, interrupting other
     * processes which share this object across a fork().
     */
    if (invalidate_fd(wrapper->client->net.fd) == Qfalse) {
      fprintf(stderr, "[WARN] mysql2 failed to invalidate FD safely, leaking some memory\n");
      close(wrapper->client->net.fd);
      return NULL;
    }
#endif

    mysql_close(wrapper->client); /* only used to free memory at this point */
  }

  return NULL;
}
Example #2
0
void decr_mysql2_client(mysql_client_wrapper *wrapper)
{
  wrapper->refcount--;

  if (wrapper->refcount == 0) {
#ifndef _WIN32
    if (wrapper->connected && !wrapper->automatic_close) {
      /* The client is being garbage collected while connected. Prevent
       * mysql_close() from sending a mysql-QUIT or from calling shutdown() on
       * the socket by invalidating it. invalidate_fd() will drop this
       * process's reference to the socket only, while a QUIT or shutdown()
       * would render the underlying connection unusable, interrupting other
       * processes which share this object across a fork().
       */
      if (invalidate_fd(wrapper->client->net.fd) == Qfalse) {
        fprintf(stderr, "[WARN] mysql2 failed to invalidate FD safely\n");
        close(wrapper->client->net.fd);
      }
    }
#endif

    nogvl_close(wrapper);
    xfree(wrapper);
  }
}
Example #3
0
int comm_snd(struct cnid_dbd_rply *rply)
{
#ifdef USE_WRITEV
    struct iovec iov[2];
    size_t towrite;
#endif

    if (!rply->namelen) {
        if (write(cur_fd, rply, sizeof(struct cnid_dbd_rply)) != sizeof(struct cnid_dbd_rply)) {
            LOG(log_error, logtype_cnid, "error writing message header: %s", strerror(errno));
            invalidate_fd(cur_fd);
            return 0;
        }
        return 1;
    }
#ifdef USE_WRITEV

    iov[0].iov_base = rply;
    iov[0].iov_len = sizeof(struct cnid_dbd_rply);
    iov[1].iov_base = rply->name;
    iov[1].iov_len = rply->namelen;
    towrite = sizeof(struct cnid_dbd_rply) +rply->namelen;

    if (writev(cur_fd, iov, 2) != towrite) {
        LOG(log_error, logtype_cnid, "error writing message : %s", strerror(errno));
        invalidate_fd(cur_fd);
        return 0;
    }
#else
    if (write(cur_fd, rply, sizeof(struct cnid_dbd_rply)) != sizeof(struct cnid_dbd_rply)) {
        LOG(log_error, logtype_cnid, "error writing message header: %s", strerror(errno));
        invalidate_fd(cur_fd);
        return 0;
    }
    if (write(cur_fd, rply->name, rply->namelen) != rply->namelen) {
        LOG(log_error, logtype_cnid, "error writing message name: %s", strerror(errno));
        invalidate_fd(cur_fd);
        return 0;
    }
#endif
    return 1;
}
Example #4
0
/* ------------ */
int comm_rcv(struct cnid_dbd_rqst *rqst, time_t timeout, const sigset_t *sigmask, time_t *now)
{
    char *nametmp;
    int b;

    if ((cur_fd = check_fd(timeout, sigmask, now)) < 0)
        return -1;

    if (!cur_fd)
        return 0;

    LOG(log_maxdebug, logtype_cnid, "comm_rcv: got data on fd %u", cur_fd);

    if (setnonblock(cur_fd, 1) != 0) {
        LOG(log_error, logtype_cnid, "comm_rcv: setnonblock: %s", strerror(errno));
        return -1;
    }

    nametmp = (char *)rqst->name;
    if ((b = readt(cur_fd, rqst, sizeof(struct cnid_dbd_rqst), 1, CNID_DBD_TIMEOUT))
        != sizeof(struct cnid_dbd_rqst)) {
        if (b)
            LOG(log_error, logtype_cnid, "error reading message header: %s", strerror(errno));
        invalidate_fd(cur_fd);
        rqst->name = nametmp;
        return 0;
    }
    rqst->name = nametmp;
    if (rqst->namelen && readt(cur_fd, (char *)rqst->name, rqst->namelen, 1, CNID_DBD_TIMEOUT)
        != rqst->namelen) {
        LOG(log_error, logtype_cnid, "error reading message name: %s", strerror(errno));
        invalidate_fd(cur_fd);
        return 0;
    }
    /* We set this to make life easier for logging. None of the other stuff
       needs zero terminated strings. */
    ((char *)(rqst->name))[rqst->namelen] = '\0';

    LOG(log_maxdebug, logtype_cnid, "comm_rcv: got %u bytes", b + rqst->namelen);

    return 1;
}
Example #5
0
int my_win_close(File fd)
{
  DBUG_ENTER("my_win_close");
  if(CloseHandle(my_get_osfhandle(fd)))
  {
    invalidate_fd(fd);
    DBUG_RETURN(0);
  }
  my_osmaperr(GetLastError());
  DBUG_RETURN(-1);
}
Example #6
0
int my_win_fclose(FILE *file)
{
  File fd;

  DBUG_ENTER("my_win_close");
  fd= my_fileno(file);
  if(fd < 0)
    DBUG_RETURN(-1);
  if(fclose(file) < 0)
    DBUG_RETURN(-1);
  invalidate_fd(fd);
  DBUG_RETURN(0);
}
Example #7
0
static VALUE disconnect_and_raise(VALUE self, VALUE error) {
  GET_CLIENT(self);

  MARK_CONN_INACTIVE(self);
  wrapper->connected = 0;

  /* Invalidate the MySQL socket to prevent further communication.
   * The GC will come along later and call mysql_close to free it.
   */
  if (invalidate_fd(wrapper->client->net.fd) == Qfalse) {
    fprintf(stderr, "[WARN] mysql2 failed to invalidate FD safely, closing unsafely\n");
    close(wrapper->client->net.fd);
  }

  rb_exc_raise(error);
}
Example #8
0
static VALUE disconnect_and_mark_inactive(VALUE self) {
  GET_CLIENT(self);

  /* Check if execution terminated while result was still being read. */
  if (!NIL_P(wrapper->active_thread)) {
    if (CONNECTED(wrapper)) {
      /* Invalidate the MySQL socket to prevent further communication. */
#ifndef _WIN32
      if (invalidate_fd(wrapper->client->net.fd) == Qfalse) {
        rb_warn("mysql2 failed to invalidate FD safely, closing unsafely\n");
        close(wrapper->client->net.fd);
      }
#else
      close(wrapper->client->net.fd);
#endif
      wrapper->client->net.fd = -1;
    }
    /* Skip mysql client check performed before command execution. */
    wrapper->client->status = MYSQL_STATUS_READY;
    wrapper->active_thread = Qnil;
  }

  return Qnil;
}