Created
June 4, 2011 06:47
-
-
Save kubo/1007677 to your computer and use it in GitHub Desktop.
patch for ruby-oci8 2.0.4. See http://rubyforge.org/forum/forum.php?thread_id=49751&forum_id=1078
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Index: ext/oci8/oci8.h | |
=================================================================== | |
--- ext/oci8/oci8.h (revision 411) | |
+++ ext/oci8/oci8.h (working copy) | |
@@ -174,7 +174,7 @@ | |
/* macros to access thread-local storage. | |
* | |
- * int oci8_tls_key_init(oci8_tls_key_t *key); | |
+ * int oci8_tls_key_init(oci8_tls_key_t *key, void (*destructor)(void*)); | |
* initialie a key to access thread-local storege | |
* This returns 0 on success or error number. | |
* | |
@@ -190,7 +190,7 @@ | |
#if defined(_WIN32) | |
#include <windows.h> | |
#define oci8_tls_key_t DWORD | |
-#define oci8_tls_key_init(key_p) \ | |
+#define oci8_tls_key_init(key_p, dummy) \ | |
((*(key_p) = TlsAlloc()), \ | |
(*(key_p) == 0xFFFFFFFF) ? GetLastError() : 0) | |
#define oci8_tls_get(key) TlsGetValue(key) | |
@@ -198,7 +198,7 @@ | |
#elif defined(HAVE_PTHREAD_H) | |
#include <pthread.h> | |
#define oci8_tls_key_t pthread_key_t | |
-#define oci8_tls_key_init(key_p) pthread_key_create((key_p), NULL) | |
+#define oci8_tls_key_init(key_p, destructor) pthread_key_create((key_p), destructor) | |
#define oci8_tls_get(key) pthread_getspecific(key) | |
#define oci8_tls_set(key, val) pthread_setspecific((key), (val)) | |
#else | |
Index: ext/oci8/env.c | |
=================================================================== | |
--- ext/oci8/env.c (revision 411) | |
+++ ext/oci8/env.c (working copy) | |
@@ -48,17 +48,42 @@ | |
*/ | |
oci8_tls_key_t oci8_tls_key; /* native thread key */ | |
-static ID id_thread_key; /* ruby's thread key */ | |
-static void oci8_free_errhp(OCIError *errhp) | |
+static void oci8_free_errhp(void *errhp) | |
{ | |
OCIHandleFree(errhp, OCI_HTYPE_ERROR); | |
} | |
+#ifdef WIN32 | |
+__declspec(dllexport) | |
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) | |
+{ | |
+ void *errhp; | |
+ | |
+ switch (fdwReason) { | |
+ case DLL_PROCESS_ATTACH: | |
+ /* do nothing */ | |
+ break; | |
+ case DLL_THREAD_ATTACH: | |
+ /* do nothing */ | |
+ break; | |
+ case DLL_THREAD_DETACH: | |
+ errhp = oci8_tls_get(oci8_tls_key); | |
+ if (errhp != NULL) { | |
+ oci8_free_errhp(errhp); | |
+ } | |
+ break; | |
+ case DLL_PROCESS_DETACH: | |
+ /* do nothing */ | |
+ break; | |
+ } | |
+ return TRUE; | |
+} | |
+#endif | |
+ | |
OCIError *oci8_make_errhp(void) | |
{ | |
OCIError *errhp; | |
- VALUE obj; | |
sword rv; | |
/* create a new errhp. */ | |
@@ -66,15 +91,6 @@ | |
if (rv != OCI_SUCCESS) { | |
oci8_env_raise(oci8_envhp, rv); | |
} | |
- /* create a new ruby object which contains errhp to make | |
- * sure that the errhp is freed when it become unnecessary. | |
- */ | |
- obj = Data_Wrap_Struct(rb_cObject, NULL, oci8_free_errhp, errhp); | |
- /* set the ruby object to ruby's thread local storage to prevent | |
- * it from being freed while the thread is available. | |
- */ | |
- rb_thread_local_aset(rb_thread_current(), id_thread_key, obj); | |
- | |
oci8_tls_set(oci8_tls_key, (void*)errhp); | |
return errhp; | |
} | |
@@ -148,8 +164,7 @@ | |
} | |
#ifdef RUBY_VM | |
- id_thread_key = rb_intern("__oci8_errhp__"); | |
- error = oci8_tls_key_init(&oci8_tls_key); | |
+ error = oci8_tls_key_init(&oci8_tls_key, oci8_free_errhp); | |
if (error != 0) { | |
rb_raise(rb_eRuntimeError, "Cannot create thread local key (errno = %d)", error); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment