Ejemplo n.º 1
0
/**
 * mongoc_buffer_append_from_stream:
 * @buffer; A mongoc_buffer_t.
 * @stream: The stream to read from.
 * @size: The number of bytes to read.
 * @timeout_msec: The number of milliseconds to wait or -1 for the default
 * @error: A location for a bson_error_t, or NULL.
 *
 * Reads from stream @size bytes and stores them in @buffer. This can be used
 * in conjunction with reading RPCs from a stream. You read from the stream
 * into this buffer and then scatter the buffer into the RPC.
 *
 * Returns: true if successful; otherwise false and @error is set.
 */
bool
_mongoc_buffer_append_from_stream (mongoc_buffer_t *buffer,
                                   mongoc_stream_t *stream,
                                   size_t size,
                                   int32_t timeout_msec,
                                   bson_error_t *error)
{
   uint8_t *buf;
   ssize_t ret;

   ENTRY;

   BSON_ASSERT (buffer);
   BSON_ASSERT (stream);
   BSON_ASSERT (size);

   BSON_ASSERT (buffer->datalen);
   BSON_ASSERT ((buffer->datalen + size) < INT_MAX);

   if (!SPACE_FOR (buffer, size)) {
      if (buffer->len) {
         memmove (&buffer->data[0], &buffer->data[buffer->off], buffer->len);
      }
      buffer->off = 0;
      if (!SPACE_FOR (buffer, size)) {
         buffer->datalen =
            bson_next_power_of_two (size + buffer->len + buffer->off);
         buffer->data = (uint8_t *) buffer->realloc_func (
            buffer->data, buffer->datalen, NULL);
      }
   }

   buf = &buffer->data[buffer->off + buffer->len];

   BSON_ASSERT ((buffer->off + buffer->len + size) <= buffer->datalen);

   ret = mongoc_stream_read (stream, buf, size, size, timeout_msec);
   if (ret != size) {
      bson_set_error (error,
                      MONGOC_ERROR_STREAM,
                      MONGOC_ERROR_STREAM_SOCKET,
                      "Failed to read %" PRIu64
                      " bytes: socket error or timeout",
                      (uint64_t) size);
      RETURN (false);
   }

   buffer->len += ret;

   RETURN (true);
}
Ejemplo n.º 2
0
char   *myrealloc(char *ptr, ssize_t len)
{
    MBLOCK *real_ptr;
    ssize_t old_len;

#ifndef NO_SHARED_EMPTY_STRINGS
    if (ptr == empty_string)
	return (mymalloc(len));
#endif

    /*
     * Note: for safety reasons the request length is a signed type. This
     * allows us to catch integer overflow problems that weren't already
     * caught up-stream.
     */
    if (len < 1)
	msg_panic("myrealloc: requested length %ld", (long) len);
#ifdef MYMALLOC_FUZZ
    len += MYMALLOC_FUZZ;
#endif
    CHECK_IN_PTR(ptr, real_ptr, old_len, "myrealloc");
    if ((real_ptr = (MBLOCK *) realloc((char *) real_ptr, SPACE_FOR(len))) == 0)
	msg_fatal("myrealloc: insufficient memory for %ld bytes: %m",
		  (long) len);
    CHECK_OUT_PTR(ptr, real_ptr, len);
    if (len > old_len)
	memset(ptr + old_len, FILLER, len - old_len);
    return (ptr);
}
Ejemplo n.º 3
0
/**
 * mongoc_buffer_append_from_stream:
 * @buffer; A mongoc_buffer_t.
 * @stream: The stream to read from.
 * @size: The number of bytes to read.
 * @timeout_msec: The number of milliseconds to wait or -1 for the default
 * @error: A location for a bson_error_t, or NULL.
 *
 * Reads from stream @size bytes and stores them in @buffer. This can be used
 * in conjunction with reading RPCs from a stream. You read from the stream
 * into this buffer and then scatter the buffer into the RPC.
 *
 * Returns: true if successful; otherwise false and @error is set.
 */
bool
_mongoc_buffer_append_from_stream (mongoc_buffer_t *buffer,
                                   mongoc_stream_t *stream,
                                   size_t           size,
                                   int32_t          timeout_msec,
                                   bson_error_t    *error)
{
    uint8_t *buf;
    ssize_t ret;

    ENTRY;

    bson_return_val_if_fail (buffer, false);
    bson_return_val_if_fail (stream, false);
    bson_return_val_if_fail (size, false);

    BSON_ASSERT (buffer->datalen);

    if (!SPACE_FOR (buffer, size)) {
        if (buffer->len) {
            memmove(&buffer->data[0], &buffer->data[buffer->off], buffer->len);
        }
        buffer->off = 0;
        if (!SPACE_FOR (buffer, size)) {
            buffer->datalen = bson_next_power_of_two ((uint32_t)size);
            buffer->data = buffer->realloc_func (buffer->data, buffer->datalen, NULL);
        }
    }

    buf = &buffer->data[buffer->off + buffer->len];
    ret = mongoc_stream_read (stream, buf, size, size, timeout_msec);
    if (ret != size) {
        bson_set_error (error,
                        MONGOC_ERROR_STREAM,
                        MONGOC_ERROR_STREAM_SOCKET,
                        "Failed to read %u bytes from socket.",
                        (unsigned)size);
        RETURN (false);
    }

    buffer->len += ret;

    RETURN (true);
}
Ejemplo n.º 4
0
/**
 * mongoc_buffer_try_append_from_stream:
 * @buffer; A mongoc_buffer_t.
 * @stream: The stream to read from.
 * @size: The number of bytes to read.
 * @timeout_msec: The number of milliseconds to wait or -1 for the default
 * @error: A location for a bson_error_t, or NULL.
 *
 * Reads from stream @size bytes and stores them in @buffer. This can be used
 * in conjunction with reading RPCs from a stream. You read from the stream
 * into this buffer and then scatter the buffer into the RPC.
 *
 * Returns: bytes read if successful; otherwise -1 and @error is set.
 */
ssize_t
_mongoc_buffer_try_append_from_stream (mongoc_buffer_t *buffer,
                                       mongoc_stream_t *stream,
                                       size_t size,
                                       int32_t timeout_msec,
                                       bson_error_t *error)
{
   uint8_t *buf;
   ssize_t ret;

   ENTRY;

   BSON_ASSERT (buffer);
   BSON_ASSERT (stream);
   BSON_ASSERT (size);

   BSON_ASSERT (buffer->datalen);
   BSON_ASSERT ((buffer->datalen + size) < INT_MAX);

   if (!SPACE_FOR (buffer, size)) {
      if (buffer->len) {
         memmove (&buffer->data[0], &buffer->data[buffer->off], buffer->len);
      }
      buffer->off = 0;
      if (!SPACE_FOR (buffer, size)) {
         buffer->datalen =
            bson_next_power_of_two (size + buffer->len + buffer->off);
         buffer->data = (uint8_t *) buffer->realloc_func (
            buffer->data, buffer->datalen, NULL);
      }
   }

   buf = &buffer->data[buffer->off + buffer->len];

   BSON_ASSERT ((buffer->off + buffer->len + size) <= buffer->datalen);

   ret = mongoc_stream_read (stream, buf, size, 0, timeout_msec);

   if (ret > 0) {
      buffer->len += ret;
   }

   RETURN (ret);
}
Ejemplo n.º 5
0
void *acl_default_realloc(const char *filename, int line,
	void *ptr, size_t len)
{
	const char *myname = "acl_default_realloc";
	MBLOCK *real_ptr;
	size_t old_len, new_len;
	const char *pname = NULL;

	if (filename && *filename)
		SET_FILE(pname, filename);
	else
		pname = __FILENAME_UNKNOWN;

#ifndef NO_SHARED_EMPTY_STRINGS
	if (ptr == empty_string)
		return acl_default_malloc(pname, line, len);
#endif

	if (len < 1) {
		acl_msg_warn("%s(%d)->%s: realloc: requested length %ld",
			pname, line, myname, (long) len);
		len = 128;
	}

	if (ptr == NULL)
		return acl_default_malloc(pname, line, len);

	CHECK_IN_PTR(ptr, real_ptr, old_len, pname, line);

	new_len = SPACE_FOR(len);
	if (new_len <= 0)
		acl_msg_fatal("%s(%d): new_len(%d) <= 0",
			myname, __LINE__, (int) new_len);
	else if (new_len >= __malloc_limit) {
		acl_msg_warn("%s(%d): new_len(%d) too large",
			myname, __LINE__, (int) new_len);
	}

#ifdef	_USE_GLIB
	if ((real_ptr = (MBLOCK *) g_realloc((char *) real_ptr, new_len)) == 0)
		acl_msg_fatal("%s(%d)->%s: realloc: insufficient memory: %s",
			pname, line, myname, strerror(errno));
#else
	if ((real_ptr = (MBLOCK *) realloc((char *) real_ptr, new_len)) == 0)
		acl_msg_fatal("%s(%d)->%s: realloc: insufficient memory: %s",
			pname, line, myname, strerror(errno));
#endif
	CHECK_OUT_PTR(ptr, real_ptr, len);
#if 0
	if (len > old_len)
		memset((char *) ptr + old_len, FILLER, len - old_len);
#endif

	return ptr;
}
Ejemplo n.º 6
0
void *acl_default_malloc(const char *filename, int line, size_t len)
{
	const char *myname = "acl_default_malloc";
	size_t new_len;
	char *ptr;
	MBLOCK *real_ptr;
	const char *pname = NULL;
#if 0
	printf("%s:%d, len: %d\r\n", filename, line, (int) len);
	acl_trace_info();
#endif

	if (filename && *filename)
		SET_FILE(pname, filename);
	else
		pname = __FILENAME_UNKNOWN;

	if (len < 1) {
		acl_msg_warn("%s(%d), %s: malloc: length %ld invalid",
			pname, line, myname, (long) len);
		len = 128;
	}

	new_len = SPACE_FOR(len);
	if (new_len <= 0)
		acl_msg_fatal("%s(%d): new_len(%d) <= 0",
			myname, __LINE__, (int) new_len);
	else if (new_len >= __malloc_limit) {
		acl_msg_warn("%s(%d): new_len(%d) too large",
			myname, __LINE__, (int) new_len);
	}

#ifdef	_USE_GLIB
	if ((real_ptr = (MBLOCK *) g_malloc(new_len)) == 0) {
		acl_msg_error("%s(%d)->%s: new_len: %d, g_malloc error(%s)",
			pname, line, myname, (int) new_len, strerror(errno));
		return 0;
	}
#else
	if ((real_ptr = (MBLOCK *) malloc(new_len)) == 0) {
		acl_msg_error("%s(%d)->%s: malloc: insufficient memory: %s, "
			"new_len: %d", pname, line, myname,
			strerror(errno), (int) new_len);
		return 0;
	}
#endif
	CHECK_OUT_PTR(ptr, real_ptr, len);
#if 0
	memset(ptr, FILLER, len);
#endif

	return ptr;
}
Ejemplo n.º 7
0
void    myfree(char *ptr)
{
    MBLOCK *real_ptr;
    ssize_t len;

#ifndef NO_SHARED_EMPTY_STRINGS
    if (ptr != empty_string) {
#endif
	CHECK_IN_PTR(ptr, real_ptr, len, "myfree");
	memset((char *) real_ptr, FILLER, SPACE_FOR(len));
	free((char *) real_ptr);
#ifndef NO_SHARED_EMPTY_STRINGS
    }
#endif
}
Ejemplo n.º 8
0
void acl_default_memstat(const char *filename, int line,
	void *ptr, size_t *len, size_t *real_len)
{
	MBLOCK *real_ptr;
	const char *pname = NULL;
	size_t old_len;

	if (filename && *filename)
		SET_FILE(pname, filename);
	else
		pname = __FILENAME_UNKNOWN;

	CHECK_PTR(ptr, real_ptr, old_len, pname, line);
	if (len)
		*len = real_ptr->length;
	if (real_len)
		*real_len = SPACE_FOR(*len);
}
Ejemplo n.º 9
0
void *acl_default_malloc(const char *filename, int line, size_t len)
{
	const char *myname = "acl_default_malloc";
	size_t new_len;
	char *ptr;
	MBLOCK *real_ptr;
	const char *pname = NULL;

	if (filename && *filename)
		SET_FILE(pname, filename);
	else
		pname = __FILENAME_UNKNOWN;

	if (len < 1)
		acl_msg_fatal("%s(%d)->%s: malloc: requested length %ld invalid",
			pname, line, myname, (long) len);

	new_len = SPACE_FOR(len);
	if (new_len <= 0)
		acl_msg_fatal("%s(%d): new_len(%d) <= 0", myname, __LINE__, (int) new_len);
	else if (new_len >= 100000000)
		acl_msg_warn("%s(%d): new_len(%d) too large", myname, __LINE__, (int) new_len);

#ifdef	_USE_GLIB
	if ((real_ptr = (MBLOCK *) g_malloc(new_len)) == 0) {
		acl_msg_error("%s(%d)->%s: g_malloc error(%s)",
			pname, line, myname, strerror(errno));
		return (0);
	}
#else
	if ((real_ptr = (MBLOCK *) malloc(new_len)) == 0) {
		acl_msg_error("%s(%d)->%s: malloc: insufficient memory: %s",
			pname, line, myname, strerror(errno));
		return (0);
	}
#endif
	CHECK_OUT_PTR(ptr, real_ptr, len);
#if 0
	memset(ptr, FILLER, len);
#endif

	return (ptr);
}
Ejemplo n.º 10
0
char   *mymalloc(ssize_t len)
{
    char   *ptr;
    MBLOCK *real_ptr;

    /*
     * Note: for safety reasons the request length is a signed type. This
     * allows us to catch integer overflow problems that weren't already
     * caught up-stream.
     */
    if (len < 1)
	msg_panic("mymalloc: requested length %ld", (long) len);
#ifdef MYMALLOC_FUZZ
    len += MYMALLOC_FUZZ;
#endif
    if ((real_ptr = (MBLOCK *) malloc(SPACE_FOR(len))) == 0)
	msg_fatal("mymalloc: insufficient memory for %ld bytes: %m",
		  (long) len);
    CHECK_OUT_PTR(ptr, real_ptr, len);
    memset(ptr, FILLER, len);
    return (ptr);
}
Ejemplo n.º 11
0
/**
 * _mongoc_buffer_fill:
 * @buffer: A mongoc_buffer_t.
 * @stream: A stream to read from.
 * @min_bytes: The minumum number of bytes to read.
 * @error: A location for a bson_error_t or NULL.
 *
 * Attempts to fill the entire buffer, or at least @min_bytes.
 *
 * Returns: The number of buffered bytes, or -1 on failure.
 */
ssize_t
_mongoc_buffer_fill (mongoc_buffer_t *buffer,
                     mongoc_stream_t *stream,
                     size_t           min_bytes,
                     int32_t          timeout_msec,
                     bson_error_t    *error)
{
   ssize_t ret;
   size_t avail_bytes;

   ENTRY;

   bson_return_val_if_fail(buffer, false);
   bson_return_val_if_fail(stream, false);
   bson_return_val_if_fail(min_bytes >= 0, false);

   BSON_ASSERT (buffer->data);
   BSON_ASSERT (buffer->datalen);

   if (min_bytes <= buffer->len) {
      RETURN (buffer->len);
   }

   min_bytes -= buffer->len;

   if (buffer->len) {
      memmove (&buffer->data[0], &buffer->data[buffer->off], buffer->len);
   }

   buffer->off = 0;

   if (!SPACE_FOR (buffer, min_bytes)) {
      buffer->datalen = bson_next_power_of_two (buffer->len + min_bytes);
      buffer->data = buffer->realloc_func (buffer->data, buffer->datalen,
                                           buffer->realloc_data);
   }

   avail_bytes = buffer->datalen - buffer->len;

   ret = mongoc_stream_read (stream,
                             &buffer->data[buffer->off + buffer->len],
                             avail_bytes, min_bytes, timeout_msec);

   if (ret == -1) {
      bson_set_error (error,
                      MONGOC_ERROR_STREAM,
                      MONGOC_ERROR_STREAM_SOCKET,
                      "Failed to buffer %u bytes within %d milliseconds.",
                      (unsigned)min_bytes, (int)timeout_msec);
      RETURN (-1);
   }

   buffer->len += ret;

   if (buffer->len < min_bytes) {
      bson_set_error (error,
                      MONGOC_ERROR_STREAM,
                      MONGOC_ERROR_STREAM_SOCKET,
                      "Could only buffer %u of %u bytes in %d milliseconds.",
                      (unsigned)buffer->len,
                      (unsigned)min_bytes,
                      (int)timeout_msec);
      RETURN (-1);
   }

   RETURN (buffer->len);
}
Ejemplo n.º 12
0
static void tls_mem_free(const char *filename, int line, void *ptr)
{
	MBLOCK *real_ptr;
	size_t len;

	CHECK_IN_PTR2(ptr, real_ptr, len, filename, line);

#if 1
	if (real_ptr->mem_slice->tid != (unsigned long) acl_pthread_self()) {
#else
	if (real_ptr->mem_slice->tid != mem_slice->tid) {
#endif
		MUTEX_LOCK(real_ptr->mem_slice);
		PRIVATE_ARRAY_PUSH(real_ptr->mem_slice->list, real_ptr);
		MUTEX_UNLOCK(real_ptr->mem_slice);
	} else
		acl_slice_pool_free(filename, line, real_ptr);
}

static void *tls_mem_alloc(const char *filename, int line, size_t len)
{
	const char *myname = "tls_mem_alloc";
	ACL_MEM_SLICE *mem_slice = acl_pthread_getspecific(__mem_slice_key);
	char *ptr;
	MBLOCK *real_ptr;

	if (mem_slice == NULL) {
		/* 每个子线程获得自己的线程局部存储内存池 */
		mem_slice = mem_slice_create();
		mem_slice->slice_list = __mem_slice_list;

		/* 将子线程的线程局部存储内存池置入全局内存池句柄集合中 */
		if (__mem_slice_list_lock)
			thread_mutex_lock(__mem_slice_list_lock);
		private_array_push(__mem_slice_list, mem_slice);
		if (__mem_slice_list_lock)
			thread_mutex_unlock(__mem_slice_list_lock);
	}

	real_ptr = (MBLOCK *) acl_slice_pool_alloc(filename, line,
			mem_slice->slice_pool, SPACE_FOR(len));
	if (real_ptr == 0) {
		acl_msg_error("%s(%d): malloc: insufficient memory",
			myname, __LINE__);
		return 0;
	}

	mem_slice->nalloc++;
	if (mem_slice->nalloc == mem_slice->nalloc_gc) {
		mem_slice->nalloc = 0;
		mem_slice_gc(mem_slice);
	}
	CHECK_OUT_PTR(ptr, real_ptr, mem_slice, len);
	return ptr;
}

static void *tls_mem_calloc(const char *filename, int line, size_t nmemb, size_t size)
{
	void *ptr = tls_mem_alloc(filename, line, nmemb * size);

	memset(ptr, 0, nmemb * size);
	return ptr;
}