diff --git a/include/SDL3/SDL_stdinc.h b/include/SDL3/SDL_stdinc.h index 63c8d2aea9..6f9a3ed8e9 100644 --- a/include/SDL3/SDL_stdinc.h +++ b/include/SDL3/SDL_stdinc.h @@ -590,11 +590,13 @@ extern SDL_DECLSPEC int SDLCALL SDL_GetNumAllocations(void); extern SDL_DECLSPEC char *SDLCALL SDL_getenv(const char *name); extern SDL_DECLSPEC int SDLCALL SDL_setenv(const char *name, const char *value, int overwrite); -extern SDL_DECLSPEC void SDLCALL SDL_qsort(void *base, size_t nmemb, size_t size, int (SDLCALL *compare) (const void *, const void *)); -extern SDL_DECLSPEC void * SDLCALL SDL_bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (SDLCALL *compare) (const void *, const void *)); +typedef int (SDLCALL *SDL_CompareCallback)(const void *a, const void *b); +extern SDL_DECLSPEC void SDLCALL SDL_qsort(void *base, size_t nmemb, size_t size, SDL_CompareCallback compare); +extern SDL_DECLSPEC void * SDLCALL SDL_bsearch(const void *key, const void *base, size_t nmemb, size_t size, SDL_CompareCallback compare); -extern SDL_DECLSPEC void SDLCALL SDL_qsort_r(void *base, size_t nmemb, size_t size, int (SDLCALL *compare) (void *, const void *, const void *), void *userdata); -extern SDL_DECLSPEC void * SDLCALL SDL_bsearch_r(const void *key, const void *base, size_t nmemb, size_t size, int (SDLCALL *compare) (void *, const void *, const void *), void *userdata); +typedef int (SDLCALL *SDL_CompareCallback_r)(void *userdata, const void *a, const void *b); +extern SDL_DECLSPEC void SDLCALL SDL_qsort_r(void *base, size_t nmemb, size_t size, SDL_CompareCallback_r compare, void *userdata); +extern SDL_DECLSPEC void * SDLCALL SDL_bsearch_r(const void *key, const void *base, size_t nmemb, size_t size, SDL_CompareCallback_r compare, void *userdata); extern SDL_DECLSPEC int SDLCALL SDL_abs(int x); diff --git a/include/SDL3/SDL_thread.h b/include/SDL3/SDL_thread.h index 3502b8c154..aed8715df6 100644 --- a/include/SDL3/SDL_thread.h +++ b/include/SDL3/SDL_thread.h @@ -490,21 +490,34 @@ extern SDL_DECLSPEC SDL_TLSID SDLCALL SDL_CreateTLS(void); */ extern SDL_DECLSPEC void * SDLCALL SDL_GetTLS(SDL_TLSID id); + +/** + * The callback used to cleanup data passed to SDL_SetTLS. + * + * This is called when a thread exits, to allow an app to + * free any resources. + * + * \param value a pointer previously handed to SDL_SetTLS. + * + * \since This datatype is available since SDL 3.0.0. + * + * \sa SDL_SetTLS + */ +typedef void (SDLCALL *SDL_TLSDestructorCallback)(void *value); + /** * Set the current thread's value associated with a thread local storage ID. * - * The function prototype for `destructor` is: + * Note that replacing a value from a previous call to this function on the + * same thread does _not_ call the previous value's destructor! * - * ```c - * void destructor(void *value) - * ``` - * - * where its parameter `value` is what was passed as `value` to SDL_SetTLS(). + * `destructor` can be NULL; it is assumed that `value` does not need + * to be cleaned up if so. * * \param id the thread local storage ID * \param value the value to associate with the ID for the current thread * \param destructor a function called when the thread exits, to free the - * value + * value. Can be NULL. * \returns 0 on success or a negative error code on failure; call * SDL_GetError() for more information. * @@ -512,7 +525,7 @@ extern SDL_DECLSPEC void * SDLCALL SDL_GetTLS(SDL_TLSID id); * * \sa SDL_GetTLS */ -extern SDL_DECLSPEC int SDLCALL SDL_SetTLS(SDL_TLSID id, const void *value, void (SDLCALL *destructor)(void*)); +extern SDL_DECLSPEC int SDLCALL SDL_SetTLS(SDL_TLSID id, const void *value, SDL_TLSDestructorCallback destructor); /** * Cleanup all TLS data for this thread. diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index df4f691cc7..5c32967050 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -775,7 +775,7 @@ SDL_DYNAPI_PROC(int,SDL_SetSurfaceColorMod,(SDL_Surface *a, Uint8 b, Uint8 c, Ui SDL_DYNAPI_PROC(int,SDL_SetSurfaceColorspace,(SDL_Surface *a, SDL_Colorspace b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_SetSurfacePalette,(SDL_Surface *a, SDL_Palette *b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_SetSurfaceRLE,(SDL_Surface *a, int b),(a,b),return) -SDL_DYNAPI_PROC(int,SDL_SetTLS,(SDL_TLSID a, const void *b, void (SDLCALL *c)(void*)),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_SetTLS,(SDL_TLSID a, const void *b, SDL_TLSDestructorCallback c),(a,b,c),return) SDL_DYNAPI_PROC(int,SDL_SetTextInputRect,(const SDL_Rect *a),(a),return) SDL_DYNAPI_PROC(int,SDL_SetTextureAlphaMod,(SDL_Texture *a, Uint8 b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_SetTextureAlphaModFloat,(SDL_Texture *a, float b),(a,b),return) @@ -905,8 +905,8 @@ SDL_DYNAPI_PROC(float,SDL_atan2f,(float a, float b),(a,b),return) SDL_DYNAPI_PROC(float,SDL_atanf,(float a),(a),return) SDL_DYNAPI_PROC(double,SDL_atof,(const char *a),(a),return) SDL_DYNAPI_PROC(int,SDL_atoi,(const char *a),(a),return) -SDL_DYNAPI_PROC(void*,SDL_bsearch,(const void *a, const void *b, size_t c, size_t d, int (SDLCALL *e)(const void *, const void *)),(a,b,c,d,e),return) -SDL_DYNAPI_PROC(void*,SDL_bsearch_r,(const void *a, const void *b, size_t c, size_t d, int (SDLCALL *e)(void *, const void *, const void *), void *f),(a,b,c,d,e,f),return) +SDL_DYNAPI_PROC(void*,SDL_bsearch,(const void *a, const void *b, size_t c, size_t d, SDL_CompareCallback e),(a,b,c,d,e),return) +SDL_DYNAPI_PROC(void*,SDL_bsearch_r,(const void *a, const void *b, size_t c, size_t d, SDL_CompareCallback_r e, void *f),(a,b,c,d,e,f),return) SDL_DYNAPI_PROC(void*,SDL_calloc,(size_t a, size_t b),(a,b),return) SDL_DYNAPI_PROC(double,SDL_ceil,(double a),(a),return) SDL_DYNAPI_PROC(float,SDL_ceilf,(float a),(a),return) @@ -985,8 +985,8 @@ SDL_DYNAPI_PROC(double,SDL_modf,(double a, double *b),(a,b),return) SDL_DYNAPI_PROC(float,SDL_modff,(float a, float *b),(a,b),return) SDL_DYNAPI_PROC(double,SDL_pow,(double a, double b),(a,b),return) SDL_DYNAPI_PROC(float,SDL_powf,(float a, float b),(a,b),return) -SDL_DYNAPI_PROC(void,SDL_qsort,(void *a, size_t b, size_t c, int (SDLCALL *d)(const void *, const void *)),(a,b,c,d),) -SDL_DYNAPI_PROC(void,SDL_qsort_r,(void *a, size_t b, size_t c, int (SDLCALL *d)(void *, const void *, const void *), void *e),(a,b,c,d,e),) +SDL_DYNAPI_PROC(void,SDL_qsort,(void *a, size_t b, size_t c, SDL_CompareCallback d),(a,b,c,d),) +SDL_DYNAPI_PROC(void,SDL_qsort_r,(void *a, size_t b, size_t c, SDL_CompareCallback_r d, void *e),(a,b,c,d,e),) SDL_DYNAPI_PROC(void*,SDL_realloc,(void *a, size_t b),(a,b),return) SDL_DYNAPI_PROC(double,SDL_round,(double a),(a),return) SDL_DYNAPI_PROC(float,SDL_roundf,(float a),(a),return) diff --git a/src/stdlib/SDL_qsort.c b/src/stdlib/SDL_qsort.c index 771712d203..20a8573f15 100644 --- a/src/stdlib/SDL_qsort.c +++ b/src/stdlib/SDL_qsort.c @@ -507,8 +507,8 @@ fprintf(stderr, "after partitioning first=#%lu last=#%lu\n", (first-(char*)base) /* ---------------------------------------------------------------------- */ -extern void SDL_qsort_r(void *base, size_t nmemb, size_t size, - int (SDLCALL * compare)(void *, const void *, const void *), void *userdata) { +void SDL_qsort_r(void *base, size_t nmemb, size_t size, + SDL_CompareCallback_r compare, void *userdata) { if (nmemb<=1) return; if (((size_t)base|size)&(WORD_BYTES-1)) @@ -525,7 +525,7 @@ static int SDLCALL qsort_non_r_bridge(void *userdata, const void *a, const void return compare(a, b); } -void SDL_qsort(void *base, size_t nmemb, size_t size, int (SDLCALL *compare) (const void *, const void *)) +void SDL_qsort(void *base, size_t nmemb, size_t size, SDL_CompareCallback compare) { SDL_qsort_r(base, nmemb, size, qsort_non_r_bridge, compare); } @@ -533,7 +533,7 @@ void SDL_qsort(void *base, size_t nmemb, size_t size, int (SDLCALL *compare) (co // Don't use the C runtime for such a simple function, since we want to allow SDLCALL callbacks and userdata. // SDL's replacement: Taken from the Public Domain C Library (PDCLib): // Permission is granted to use, modify, and / or redistribute at will. -void *SDL_bsearch_r(const void *key, const void *base, size_t nmemb, size_t size, int (SDLCALL *compare)(void *, const void *, const void *), void *userdata) +void *SDL_bsearch_r(const void *key, const void *base, size_t nmemb, size_t size, SDL_CompareCallback_r compare, void *userdata) { const void *pivot; size_t corr; @@ -558,7 +558,7 @@ void *SDL_bsearch_r(const void *key, const void *base, size_t nmemb, size_t size return NULL; } -void *SDL_bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (SDLCALL *compare)(const void *, const void *)) +void *SDL_bsearch(const void *key, const void *base, size_t nmemb, size_t size, SDL_CompareCallback compare) { // qsort_non_r_bridge just happens to match calling conventions, so reuse it. return SDL_bsearch_r(key, base, nmemb, size, qsort_non_r_bridge, compare); diff --git a/src/thread/SDL_thread.c b/src/thread/SDL_thread.c index 909dc78295..1589a56ad5 100644 --- a/src/thread/SDL_thread.c +++ b/src/thread/SDL_thread.c @@ -43,7 +43,7 @@ void *SDL_GetTLS(SDL_TLSID id) return storage->array[id - 1].data; } -int SDL_SetTLS(SDL_TLSID id, const void *value, void(SDLCALL *destructor)(void *)) +int SDL_SetTLS(SDL_TLSID id, const void *value, SDL_TLSDestructorCallback destructor) { SDL_TLSData *storage;