mirror of
https://github.com/shadowsocks/shadowsocks-libev.git
synced 2026-11-03 16:45:53 +00:00
Update libcork to 0.15.0 (#856)
Signed-off-by: Syrone Wong <wong.syrone@gmail.com>
This commit is contained in:
@@ -1,10 +1,9 @@
|
||||
/* -*- coding: utf-8 -*-
|
||||
* ----------------------------------------------------------------------
|
||||
* Copyright © 2011-2013, RedJack, LLC.
|
||||
* Copyright © 2011-2015, RedJack, LLC.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Please see the COPYING file in this distribution for license
|
||||
* details.
|
||||
* Please see the COPYING file in this distribution for license details.
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@@ -28,6 +27,11 @@
|
||||
/* Otherwise autodetect! */
|
||||
|
||||
|
||||
/**** VERSION ****/
|
||||
|
||||
#include <libcork/config/version.h>
|
||||
|
||||
|
||||
/**** ARCHITECTURES ****/
|
||||
|
||||
#include <libcork/config/arch.h>
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/* -*- coding: utf-8 -*-
|
||||
* ----------------------------------------------------------------------
|
||||
* Copyright © 2015, RedJack, LLC.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Please see the COPYING file in this distribution for license details.
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef LIBCORK_CONFIG_VERSION_H
|
||||
#define LIBCORK_CONFIG_VERSION_H
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Library version
|
||||
*/
|
||||
|
||||
#define CORK_CONFIG_VERSION_MAJOR 0
|
||||
#define CORK_CONFIG_VERSION_MINOR 15
|
||||
#define CORK_CONFIG_VERSION_PATCH 0
|
||||
#define CORK_CONFIG_VERSION_STRING "0.15.0"
|
||||
#define CORK_CONFIG_REVISION "d6ecc2cfbcdf5013038a72b4544f7d9e6eb8f92d"
|
||||
|
||||
|
||||
#endif /* LIBCORK_CONFIG_VERSION_H */
|
||||
@@ -1,75 +1,409 @@
|
||||
/* -*- coding: utf-8 -*-
|
||||
* ----------------------------------------------------------------------
|
||||
* Copyright © 2011-2012, RedJack, LLC.
|
||||
* Copyright © 2011-2014, RedJack, LLC.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Please see the COPYING file in this distribution for license
|
||||
* details.
|
||||
* Please see the COPYING file in this distribution for license details.
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef LIBCORK_CORE_ALLOCATOR_H
|
||||
#define LIBCORK_CORE_ALLOCATOR_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <libcork/core/api.h>
|
||||
#include <libcork/core/attributes.h>
|
||||
#include <libcork/core/callbacks.h>
|
||||
#include <libcork/core/error.h>
|
||||
#include <libcork/core/types.h>
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Recoverable
|
||||
* Allocator interface
|
||||
*/
|
||||
|
||||
#define cork_xmalloc malloc
|
||||
#define cork_xcalloc calloc
|
||||
#define cork_xfree free
|
||||
struct cork_alloc;
|
||||
|
||||
#if CORK_HAVE_REALLOCF
|
||||
#define cork_xrealloc reallocf
|
||||
#else
|
||||
CORK_API void *
|
||||
cork_xrealloc(void *ptr, size_t new_size) CORK_ATTR_MALLOC;
|
||||
#endif
|
||||
typedef void *
|
||||
(*cork_alloc_calloc_f)(const struct cork_alloc *alloc,
|
||||
size_t count, size_t size);
|
||||
|
||||
/* type-based macros */
|
||||
#define cork_xnew(type) ((type *) cork_xmalloc(sizeof(type)))
|
||||
typedef void *
|
||||
(*cork_alloc_malloc_f)(const struct cork_alloc *alloc, size_t size);
|
||||
|
||||
/* string-related functions */
|
||||
/* Must not free `ptr` if allocation fails. */
|
||||
typedef void *
|
||||
(*cork_alloc_realloc_f)(const struct cork_alloc *alloc, void *ptr,
|
||||
size_t old_size, size_t new_size);
|
||||
|
||||
CORK_API const char *
|
||||
cork_xstrdup(const char *str);
|
||||
typedef void
|
||||
(*cork_alloc_free_f)(const struct cork_alloc *alloc, void *ptr, size_t size);
|
||||
|
||||
struct cork_alloc {
|
||||
const struct cork_alloc *parent;
|
||||
void *user_data;
|
||||
cork_free_f free_user_data;
|
||||
cork_alloc_calloc_f calloc;
|
||||
cork_alloc_malloc_f malloc;
|
||||
cork_alloc_realloc_f realloc;
|
||||
cork_alloc_calloc_f xcalloc;
|
||||
cork_alloc_malloc_f xmalloc;
|
||||
cork_alloc_realloc_f xrealloc;
|
||||
cork_alloc_free_f free;
|
||||
};
|
||||
|
||||
/* NOT thread-safe; must be called before most other libcork functions.
|
||||
* Allocator will automatically be freed at process exit. */
|
||||
CORK_API struct cork_alloc *
|
||||
cork_alloc_new_alloc(const struct cork_alloc *parent);
|
||||
|
||||
CORK_API const char *
|
||||
cork_xstrndup(const char *str, size_t size);
|
||||
|
||||
CORK_API void
|
||||
cork_strfree(const char *str);
|
||||
cork_alloc_set_user_data(struct cork_alloc *alloc,
|
||||
void *user_data, cork_free_f free_user_data);
|
||||
|
||||
/* These variants must always return a valid pointer. If allocation fails, they
|
||||
* should abort the process or transfer control in some other way to an error
|
||||
* handler or cleanup routine.
|
||||
*
|
||||
* If you only provide implementations of the `x` variants, we'll provide
|
||||
* default implementations of these that abort the process if a memory
|
||||
* allocation fails. */
|
||||
|
||||
CORK_API void
|
||||
cork_alloc_set_calloc(struct cork_alloc *alloc, cork_alloc_calloc_f calloc);
|
||||
|
||||
CORK_API void
|
||||
cork_alloc_set_malloc(struct cork_alloc *alloc, cork_alloc_malloc_f malloc);
|
||||
|
||||
CORK_API void
|
||||
cork_alloc_set_realloc(struct cork_alloc *alloc, cork_alloc_realloc_f realloc);
|
||||
|
||||
/* These variants can return a NULL pointer if allocation fails. */
|
||||
|
||||
CORK_API void
|
||||
cork_alloc_set_xcalloc(struct cork_alloc *alloc, cork_alloc_calloc_f xcalloc);
|
||||
|
||||
CORK_API void
|
||||
cork_alloc_set_xmalloc(struct cork_alloc *alloc, cork_alloc_malloc_f xmalloc);
|
||||
|
||||
CORK_API void
|
||||
cork_alloc_set_xrealloc(struct cork_alloc *alloc,
|
||||
cork_alloc_realloc_f xrealloc);
|
||||
|
||||
|
||||
CORK_API void
|
||||
cork_alloc_set_free(struct cork_alloc *alloc, cork_alloc_free_f free);
|
||||
|
||||
|
||||
/* Low-level use of an allocator. */
|
||||
|
||||
CORK_ATTR_MALLOC
|
||||
CORK_ATTR_UNUSED
|
||||
static void *
|
||||
cork_alloc_calloc(const struct cork_alloc *alloc, size_t count, size_t size)
|
||||
{
|
||||
return alloc->calloc(alloc, count, size);
|
||||
}
|
||||
|
||||
CORK_ATTR_MALLOC
|
||||
CORK_ATTR_UNUSED
|
||||
static void *
|
||||
cork_alloc_malloc(const struct cork_alloc *alloc, size_t size)
|
||||
{
|
||||
return alloc->malloc(alloc, size);
|
||||
}
|
||||
|
||||
CORK_ATTR_MALLOC
|
||||
CORK_ATTR_UNUSED
|
||||
static void *
|
||||
cork_alloc_realloc(const struct cork_alloc *alloc, void *ptr,
|
||||
size_t old_size, size_t new_size)
|
||||
{
|
||||
return alloc->realloc(alloc, ptr, old_size, new_size);
|
||||
}
|
||||
|
||||
CORK_ATTR_MALLOC
|
||||
CORK_ATTR_UNUSED
|
||||
static void *
|
||||
cork_alloc_xcalloc(const struct cork_alloc *alloc, size_t count, size_t size)
|
||||
{
|
||||
return alloc->xcalloc(alloc, count, size);
|
||||
}
|
||||
|
||||
CORK_ATTR_MALLOC
|
||||
CORK_ATTR_UNUSED
|
||||
static void *
|
||||
cork_alloc_xmalloc(const struct cork_alloc *alloc, size_t size)
|
||||
{
|
||||
return alloc->xmalloc(alloc, size);
|
||||
}
|
||||
|
||||
CORK_ATTR_MALLOC
|
||||
CORK_ATTR_UNUSED
|
||||
static void *
|
||||
cork_alloc_xrealloc(const struct cork_alloc *alloc, void *ptr,
|
||||
size_t old_size, size_t new_size)
|
||||
{
|
||||
return alloc->xrealloc(alloc, ptr, old_size, new_size);
|
||||
}
|
||||
|
||||
CORK_ATTR_MALLOC
|
||||
CORK_ATTR_UNUSED
|
||||
static void *
|
||||
cork_alloc_xreallocf(const struct cork_alloc *alloc, void *ptr,
|
||||
size_t old_size, size_t new_size)
|
||||
{
|
||||
void *result = alloc->xrealloc(alloc, ptr, old_size, new_size);
|
||||
if (result == NULL) {
|
||||
alloc->free(alloc, ptr, old_size);
|
||||
return NULL;
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
CORK_ATTR_UNUSED
|
||||
static void
|
||||
cork_alloc_free(const struct cork_alloc *alloc, void *ptr, size_t size)
|
||||
{
|
||||
return alloc->free(alloc, ptr, size);
|
||||
}
|
||||
|
||||
CORK_ATTR_UNUSED
|
||||
static void
|
||||
cork_alloc_cfree(const struct cork_alloc *alloc, void *ptr,
|
||||
size_t count, size_t size)
|
||||
{
|
||||
assert(count < (SIZE_MAX / size));
|
||||
return alloc->free(alloc, ptr, count * size);
|
||||
}
|
||||
|
||||
#define cork_alloc_new(alloc, type) \
|
||||
cork_alloc_malloc((alloc), sizeof(type))
|
||||
#define cork_alloc_xnew(alloc, type) \
|
||||
cork_alloc_xmalloc((alloc), sizeof(type))
|
||||
#define cork_alloc_delete(alloc, type, ptr) \
|
||||
cork_alloc_free((alloc), (ptr), sizeof(type))
|
||||
|
||||
/* string-related helper functions */
|
||||
|
||||
CORK_ATTR_MALLOC
|
||||
CORK_API const char *
|
||||
cork_alloc_strdup(const struct cork_alloc *alloc, const char *str);
|
||||
|
||||
CORK_ATTR_MALLOC
|
||||
CORK_API const char *
|
||||
cork_alloc_strndup(const struct cork_alloc *alloc,
|
||||
const char *str, size_t size);
|
||||
|
||||
CORK_ATTR_MALLOC
|
||||
CORK_API const char *
|
||||
cork_alloc_xstrdup(const struct cork_alloc *alloc, const char *str);
|
||||
|
||||
CORK_ATTR_MALLOC
|
||||
CORK_API const char *
|
||||
cork_alloc_xstrndup(const struct cork_alloc *alloc,
|
||||
const char *str, size_t size);
|
||||
|
||||
CORK_API void
|
||||
cork_alloc_strfree(const struct cork_alloc *alloc, const char *str);
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Abort on failure
|
||||
* Using the allocator interface
|
||||
*/
|
||||
|
||||
CORK_API void *
|
||||
cork_malloc(size_t size) CORK_ATTR_MALLOC;
|
||||
/* All of the functions that you use to actually allocate memory assume that
|
||||
* cork_current_allocator() returns the allocator instance that should be used.
|
||||
* Your easiest approach is to do nothing special; in that case, all of the
|
||||
* libcork memory allocation functions will transparently use the standard
|
||||
* malloc/free family of functions.
|
||||
*
|
||||
* If you're writing a library, and want to allow your library clients to
|
||||
* provide a separate custom memory allocator then the one they can already
|
||||
* override for libcork itself, you should declare a pair of functions for
|
||||
* getting and setting your library's current allocator (like libcork itself
|
||||
* does), and (only when compiling the source of your library) define
|
||||
* `cork_current_allocator` as a macro that aliases the getter function. That
|
||||
* will cause the libcork memory allocation functions to use whichever allocator
|
||||
* your library user has provided.
|
||||
*
|
||||
* If you're writing an application, and want to provide a single allocator that
|
||||
* all libcork-using libraries will pick up, just call cork_set_allocator before
|
||||
* calling any other library functions. Other libraries will use this as a
|
||||
* default and everything that uses libcork's memory allocation functions will
|
||||
* use your custom allocator. */
|
||||
|
||||
CORK_API void *
|
||||
cork_calloc(size_t count, size_t size) CORK_ATTR_MALLOC;
|
||||
|
||||
CORK_API void *
|
||||
cork_realloc(void *ptr, size_t new_size) CORK_ATTR_MALLOC;
|
||||
/* libcork's current allocator */
|
||||
|
||||
CORK_API const char *
|
||||
cork_strdup(const char *src) CORK_ATTR_MALLOC;
|
||||
extern const struct cork_alloc *cork_allocator;
|
||||
|
||||
CORK_API const char *
|
||||
cork_strndup(const char *src, size_t size) CORK_ATTR_MALLOC;
|
||||
/* We take control and will free when the process exits. This is *NOT*
|
||||
* thread-safe; it's only safe to call before you've called *ANY* other libcork
|
||||
* function (or any function from any other library that uses libcork). You can
|
||||
* only call this at most once. */
|
||||
CORK_API void
|
||||
cork_set_allocator(const struct cork_alloc *alloc);
|
||||
|
||||
#define cork_new(type) \
|
||||
cork_malloc(sizeof(type))
|
||||
|
||||
/* The current allocator of whichever library is being compiled. */
|
||||
|
||||
#if !defined(cork_current_allocator)
|
||||
#define cork_current_allocator() (cork_allocator)
|
||||
#endif
|
||||
|
||||
|
||||
/* using an allocator */
|
||||
|
||||
CORK_ATTR_MALLOC
|
||||
CORK_ATTR_UNUSED
|
||||
static void *
|
||||
cork_calloc(size_t count, size_t size)
|
||||
{
|
||||
const struct cork_alloc *alloc = cork_current_allocator();
|
||||
return cork_alloc_calloc(alloc, count, size);
|
||||
}
|
||||
|
||||
CORK_ATTR_MALLOC
|
||||
CORK_ATTR_UNUSED
|
||||
static void *
|
||||
cork_malloc(size_t size)
|
||||
{
|
||||
const struct cork_alloc *alloc = cork_current_allocator();
|
||||
return cork_alloc_malloc(alloc, size);
|
||||
}
|
||||
|
||||
CORK_ATTR_MALLOC
|
||||
CORK_ATTR_UNUSED
|
||||
static void *
|
||||
cork_realloc(void *ptr, size_t old_size, size_t new_size)
|
||||
{
|
||||
const struct cork_alloc *alloc = cork_current_allocator();
|
||||
return cork_alloc_realloc(alloc, ptr, old_size, new_size);
|
||||
}
|
||||
|
||||
CORK_ATTR_MALLOC
|
||||
CORK_ATTR_UNUSED
|
||||
static void *
|
||||
cork_xcalloc(size_t count, size_t size)
|
||||
{
|
||||
const struct cork_alloc *alloc = cork_current_allocator();
|
||||
return cork_alloc_xcalloc(alloc, count, size);
|
||||
}
|
||||
|
||||
CORK_ATTR_MALLOC
|
||||
CORK_ATTR_UNUSED
|
||||
static void *
|
||||
cork_xmalloc(size_t size)
|
||||
{
|
||||
const struct cork_alloc *alloc = cork_current_allocator();
|
||||
return cork_alloc_xmalloc(alloc, size);
|
||||
}
|
||||
|
||||
CORK_ATTR_MALLOC
|
||||
CORK_ATTR_UNUSED
|
||||
static void *
|
||||
cork_xrealloc(void *ptr, size_t old_size, size_t new_size)
|
||||
{
|
||||
const struct cork_alloc *alloc = cork_current_allocator();
|
||||
return cork_alloc_xrealloc(alloc, ptr, old_size, new_size);
|
||||
}
|
||||
|
||||
CORK_ATTR_MALLOC
|
||||
CORK_ATTR_UNUSED
|
||||
static void *
|
||||
cork_xreallocf(void *ptr, size_t old_size, size_t new_size)
|
||||
{
|
||||
const struct cork_alloc *alloc = cork_current_allocator();
|
||||
return cork_alloc_xreallocf(alloc, ptr, old_size, new_size);
|
||||
}
|
||||
|
||||
CORK_ATTR_UNUSED
|
||||
static void
|
||||
cork_free(void *ptr, size_t size)
|
||||
{
|
||||
const struct cork_alloc *alloc = cork_current_allocator();
|
||||
cork_alloc_free(alloc, ptr, size);
|
||||
}
|
||||
|
||||
CORK_ATTR_UNUSED
|
||||
static void
|
||||
cork_cfree(void *ptr, size_t count, size_t size)
|
||||
{
|
||||
const struct cork_alloc *alloc = cork_current_allocator();
|
||||
cork_alloc_cfree(alloc, ptr, count, size);
|
||||
}
|
||||
|
||||
#define cork_new(type) cork_malloc(sizeof(type))
|
||||
#define cork_xnew(type) cork_xmalloc(sizeof(type))
|
||||
#define cork_delete(type, ptr) cork_free((ptr), sizeof(type))
|
||||
|
||||
|
||||
/* string-related helper functions */
|
||||
|
||||
CORK_ATTR_MALLOC
|
||||
CORK_ATTR_UNUSED
|
||||
static const char *
|
||||
cork_strdup(const char *str)
|
||||
{
|
||||
const struct cork_alloc *alloc = cork_current_allocator();
|
||||
return cork_alloc_strdup(alloc, str);
|
||||
}
|
||||
|
||||
CORK_ATTR_MALLOC
|
||||
CORK_ATTR_UNUSED
|
||||
static const char *
|
||||
cork_strndup(const char *str, size_t size)
|
||||
{
|
||||
const struct cork_alloc *alloc = cork_current_allocator();
|
||||
return cork_alloc_strndup(alloc, str, size);
|
||||
}
|
||||
|
||||
CORK_ATTR_MALLOC
|
||||
CORK_ATTR_UNUSED
|
||||
static const char *
|
||||
cork_xstrdup(const char *str)
|
||||
{
|
||||
const struct cork_alloc *alloc = cork_current_allocator();
|
||||
return cork_alloc_xstrdup(alloc, str);
|
||||
}
|
||||
|
||||
CORK_ATTR_MALLOC
|
||||
CORK_ATTR_UNUSED
|
||||
static const char *
|
||||
cork_xstrndup(const char *str, size_t size)
|
||||
{
|
||||
const struct cork_alloc *alloc = cork_current_allocator();
|
||||
return cork_alloc_xstrndup(alloc, str, size);
|
||||
}
|
||||
|
||||
CORK_ATTR_UNUSED
|
||||
static void
|
||||
cork_strfree(const char *str)
|
||||
{
|
||||
const struct cork_alloc *alloc = cork_current_allocator();
|
||||
return cork_alloc_strfree(alloc, str);
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Debugging allocator
|
||||
*/
|
||||
|
||||
/* An allocator that adds some additional debugging checks:
|
||||
*
|
||||
* - We verify that every "free" call (cork_free, cork_cfree, cork_delete,
|
||||
* cork_realloc) is passed the "correct" size — i.e., the same size that was
|
||||
* passed in to the correspond "new" call (cork_malloc, cork_calloc,
|
||||
* cork_realloc, cork_new).
|
||||
*/
|
||||
|
||||
struct cork_alloc *
|
||||
cork_debug_alloc_new(const struct cork_alloc *parent);
|
||||
|
||||
|
||||
#endif /* LIBCORK_CORE_ALLOCATOR_H */
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
/* -*- coding: utf-8 -*-
|
||||
* ----------------------------------------------------------------------
|
||||
* Copyright © 2012, RedJack, LLC.
|
||||
* Copyright © 2012-2015, RedJack, LLC.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Please see the COPYING file in this distribution for license
|
||||
* details.
|
||||
* Please see the COPYING file in this distribution for license details.
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef LIBCORK_CORE_API_H
|
||||
#define LIBCORK_CORE_API_H
|
||||
|
||||
#include <libcork/config.h>
|
||||
#include <libcork/core/attributes.h>
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Calling conventions
|
||||
*/
|
||||
|
||||
/* If you're using libcork as a shared library, you don't need to do anything
|
||||
* special; the following will automatically set things up so that libcork's
|
||||
* public symbols are imported from the library. When we build the shared
|
||||
@@ -22,4 +27,30 @@
|
||||
#define CORK_API CORK_IMPORT
|
||||
#endif
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Library version
|
||||
*/
|
||||
|
||||
#define CORK_VERSION_MAJOR CORK_CONFIG_VERSION_MAJOR
|
||||
#define CORK_VERSION_MINOR CORK_CONFIG_VERSION_MINOR
|
||||
#define CORK_VERSION_PATCH CORK_CONFIG_VERSION_PATCH
|
||||
|
||||
#define CORK_MAKE_VERSION(major, minor, patch) \
|
||||
((major * 1000000) + (minor * 1000) + patch)
|
||||
|
||||
#define CORK_VERSION \
|
||||
CORK_MAKE_VERSION(CORK_VERSION_MAJOR, \
|
||||
CORK_VERSION_MINOR, \
|
||||
CORK_VERSION_PATCH)
|
||||
|
||||
CORK_API const char *
|
||||
cork_version_string(void)
|
||||
CORK_ATTR_CONST;
|
||||
|
||||
CORK_API const char *
|
||||
cork_revision_string(void)
|
||||
CORK_ATTR_CONST;
|
||||
|
||||
|
||||
#endif /* LIBCORK_CORE_API_H */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- coding: utf-8 -*-
|
||||
* ----------------------------------------------------------------------
|
||||
* Copyright © 2013, RedJack, LLC.
|
||||
* Copyright © 2013-2014, RedJack, LLC.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Please see the COPYING file in this distribution for license details.
|
||||
@@ -39,5 +39,8 @@ typedef void
|
||||
typedef void *
|
||||
(*cork_new_f)(void *user_data);
|
||||
|
||||
typedef int
|
||||
(*cork_run_f)(void *user_data);
|
||||
|
||||
|
||||
#endif /* LIBCORK_CORE_CALLBACKS_H */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- coding: utf-8 -*-
|
||||
* ----------------------------------------------------------------------
|
||||
* Copyright © 2012-2013, RedJack, LLC.
|
||||
* Copyright © 2012-2015, RedJack, LLC.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Please see the COPYING file in this distribution for license details.
|
||||
@@ -41,6 +41,18 @@ CORK_API void
|
||||
cork_mempool_free(struct cork_mempool *mp);
|
||||
|
||||
|
||||
CORK_API void
|
||||
cork_mempool_set_user_data(struct cork_mempool *mp,
|
||||
void *user_data, cork_free_f free_user_data);
|
||||
|
||||
CORK_API void
|
||||
cork_mempool_set_init_object(struct cork_mempool *mp, cork_init_f init_object);
|
||||
|
||||
CORK_API void
|
||||
cork_mempool_set_done_object(struct cork_mempool *mp, cork_done_f done_object);
|
||||
|
||||
/* Deprecated; you should now use separate calls to cork_mempool_set_user_data,
|
||||
* cork_mempool_set_init_object, and cork_mempool_set_done_object. */
|
||||
CORK_API void
|
||||
cork_mempool_set_callbacks(struct cork_mempool *mp,
|
||||
void *user_data, cork_free_f free_user_data,
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
/* -*- coding: utf-8 -*-
|
||||
* ----------------------------------------------------------------------
|
||||
* Copyright © 2012-2013, RedJack, LLC.
|
||||
* Copyright © 2012-2014, RedJack, LLC.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Please see the COPYING file in this distribution for license
|
||||
* details.
|
||||
* Please see the COPYING file in this distribution for license details.
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@@ -14,6 +13,7 @@
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <libcork/core/api.h>
|
||||
#include <libcork/core/callbacks.h>
|
||||
#include <libcork/core/types.h>
|
||||
#include <libcork/ds/stream.h>
|
||||
#include <libcork/threads/basics.h>
|
||||
@@ -126,7 +126,8 @@ struct cork_subprocess;
|
||||
|
||||
/* Takes control of body */
|
||||
CORK_API struct cork_subprocess *
|
||||
cork_subprocess_new(struct cork_thread_body *body,
|
||||
cork_subprocess_new(void *user_data, cork_free_f free_user_data,
|
||||
cork_run_f run,
|
||||
struct cork_stream_consumer *stdout_consumer,
|
||||
struct cork_stream_consumer *stderr_consumer,
|
||||
int *exit_code);
|
||||
|
||||
@@ -23,14 +23,19 @@
|
||||
|
||||
#define cork_int_atomic_add __sync_add_and_fetch
|
||||
#define cork_uint_atomic_add __sync_add_and_fetch
|
||||
#define cork_size_atomic_add __sync_add_and_fetch
|
||||
#define cork_int_atomic_pre_add __sync_fetch_and_add
|
||||
#define cork_uint_atomic_pre_add __sync_fetch_and_add
|
||||
#define cork_size_atomic_pre_add __sync_fetch_and_add
|
||||
#define cork_int_atomic_sub __sync_sub_and_fetch
|
||||
#define cork_uint_atomic_sub __sync_sub_and_fetch
|
||||
#define cork_size_atomic_sub __sync_sub_and_fetch
|
||||
#define cork_int_atomic_pre_sub __sync_fetch_and_sub
|
||||
#define cork_uint_atomic_pre_sub __sync_fetch_and_sub
|
||||
#define cork_size_atomic_pre_sub __sync_fetch_and_sub
|
||||
#define cork_int_cas __sync_val_compare_and_swap
|
||||
#define cork_uint_cas __sync_val_compare_and_swap
|
||||
#define cork_size_cas __sync_val_compare_and_swap
|
||||
#define cork_ptr_cas __sync_val_compare_and_swap
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
/* -*- coding: utf-8 -*-
|
||||
* ----------------------------------------------------------------------
|
||||
* Copyright © 2012, RedJack, LLC.
|
||||
* Copyright © 2012-2014, RedJack, LLC.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Please see the COPYING file in this distribution for license
|
||||
* details.
|
||||
* Please see the COPYING file in this distribution for license details.
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@@ -15,6 +14,7 @@
|
||||
|
||||
#include <libcork/core/api.h>
|
||||
#include <libcork/core/attributes.h>
|
||||
#include <libcork/core/callbacks.h>
|
||||
#include <libcork/threads/atomics.h>
|
||||
|
||||
|
||||
@@ -32,22 +32,6 @@ CORK_API cork_thread_id
|
||||
cork_current_thread_get_id(void);
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Main functions
|
||||
*/
|
||||
|
||||
struct cork_thread_body {
|
||||
int
|
||||
(*run)(struct cork_thread_body *self);
|
||||
|
||||
void
|
||||
(*free)(struct cork_thread_body *self);
|
||||
};
|
||||
|
||||
#define cork_thread_body_run(tb) ((tb)->run((tb)))
|
||||
#define cork_thread_body_free(tb) ((tb)->free((tb)))
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Threads
|
||||
*/
|
||||
@@ -60,7 +44,9 @@ CORK_API struct cork_thread *
|
||||
cork_current_thread_get(void);
|
||||
|
||||
CORK_API struct cork_thread *
|
||||
cork_thread_new(const char *name, struct cork_thread_body *body);
|
||||
cork_thread_new(const char *name,
|
||||
void *user_data, cork_free_f free_user_data,
|
||||
cork_run_f run);
|
||||
|
||||
/* Thread must not have been started yet. */
|
||||
CORK_API void
|
||||
@@ -171,20 +157,23 @@ NAME##_get(void) \
|
||||
return &NAME##__tls; \
|
||||
}
|
||||
|
||||
#define cork_tls_with_alloc(TYPE, NAME, allocate, deallocate) \
|
||||
cork_tls(TYPE, NAME)
|
||||
|
||||
#elif CORK_HAVE_PTHREADS
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <libcork/core/allocator.h>
|
||||
|
||||
#define cork_tls(TYPE, NAME) \
|
||||
#define cork_tls_with_alloc(TYPE, NAME, allocate, deallocate) \
|
||||
static pthread_key_t NAME##__tls_key; \
|
||||
cork_once_barrier(NAME##__tls_barrier); \
|
||||
\
|
||||
static void \
|
||||
NAME##__tls_destroy(void *vself) \
|
||||
NAME##__tls_destroy(void *self) \
|
||||
{ \
|
||||
free(vself); \
|
||||
deallocate(self); \
|
||||
} \
|
||||
\
|
||||
static void \
|
||||
@@ -202,12 +191,28 @@ NAME##_get(void) \
|
||||
cork_once(NAME##__tls_barrier, NAME##__create_key()); \
|
||||
self = pthread_getspecific(NAME##__tls_key); \
|
||||
if (CORK_UNLIKELY(self == NULL)) { \
|
||||
self = cork_calloc(1, sizeof(TYPE)); \
|
||||
self = allocate(); \
|
||||
pthread_setspecific(NAME##__tls_key, self); \
|
||||
} \
|
||||
return self; \
|
||||
}
|
||||
|
||||
#define cork_tls(TYPE, NAME) \
|
||||
\
|
||||
static TYPE * \
|
||||
NAME##__tls_allocate(void) \
|
||||
{ \
|
||||
return cork_calloc(1, sizeof(TYPE)); \
|
||||
} \
|
||||
\
|
||||
static void \
|
||||
NAME##__tls_deallocate(void *vself) \
|
||||
{ \
|
||||
cork_cfree(vself, 1, sizeof(TYPE)); \
|
||||
} \
|
||||
\
|
||||
cork_tls_with_alloc(TYPE, NAME, NAME##__tls_allocate, NAME##__tls_deallocate);
|
||||
|
||||
#else
|
||||
#error "No thread-local storage implementation!"
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user