Skip to content

Instantly share code, notes, and snippets.

@kubo
Created June 4, 2011 06:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kubo/1007677 to your computer and use it in GitHub Desktop.
Save kubo/1007677 to your computer and use it in GitHub Desktop.
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