[前][次][番号順一覧][スレッド一覧]

ruby-changes:26815

From: nobu <ko1@a...>
Date: Fri, 18 Jan 2013 11:23:57 +0900 (JST)
Subject: [ruby-changes:26815] nobu:r38867 (trunk): win32ole: OLE initialize per threads

nobu	2013-01-18 11:23:37 +0900 (Fri, 18 Jan 2013)

  New Revision: 38867

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=38867

  Log:
    win32ole: OLE initialize per threads
    
    * ext/win32ole/win32ole.c (ole_initialize): initialize OLE for each
      threads.  [Bug #2618] [ruby-core:27634]

  Modified files:
    trunk/ChangeLog
    trunk/ext/win32ole/extconf.rb
    trunk/ext/win32ole/win32ole.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 38866)
+++ ChangeLog	(revision 38867)
@@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Fri Jan 18 11:23:34 2013  Nobuyoshi Nakada  <nobu@r...>
+
+	* ext/win32ole/win32ole.c (ole_initialize): initialize OLE for each
+	  threads.  [Bug #2618] [ruby-core:27634]
+
 Thu Jan 17 22:10:35 2013  Kouhei Sutou  <kou@c...>
 
 	* lib/rubygems/ext/builder.rb (Gem::Ext::Builder.make): Remove
Index: ext/win32ole/win32ole.c
===================================================================
--- ext/win32ole/win32ole.c	(revision 38866)
+++ ext/win32ole/win32ole.c	(revision 38867)
@@ -214,7 +214,16 @@ VALUE cWIN32OLE_PROPERTY; https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L214
 
 static VALUE ary_ole_event;
 static ID id_events;
-static BOOL g_ole_initialized = FALSE;
+#ifdef RB_THREAD_SPECIFIC
+static RB_THREAD_SPECIFIC BOOL g_ole_initialized;
+# define g_ole_initialized_init() ((void)0)
+# define g_ole_initialized_set(val) (g_ole_initialized = (val))
+#else
+static volatile DWORD g_ole_initialized_key = TLS_OUT_OF_INDEXES;
+# define g_ole_initialized (BOOL)TlsGetValue(g_ole_initialized_key)
+# define g_ole_initialized_init() (g_ole_initialized_key = TlsAlloc())
+# define g_ole_initialized_set(val) TlsSetValue(g_ole_initialized_key, (void*)(val))
+#endif
 static BOOL g_cp_installed = FALSE;
 static BOOL g_lcid_installed = FALSE;
 static HINSTANCE ghhctrl = NULL;
@@ -370,9 +379,7 @@ static BOOL CALLBACK installed_lcid_proc https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L379
 static BOOL lcid_installed(LCID lcid);
 static VALUE fole_s_set_locale(VALUE self, VALUE vlcid);
 static VALUE fole_s_create_guid(VALUE self);
-static void  ole_pure_initialize(void);
 static VALUE fole_s_ole_initialize(VALUE self);
-static void  ole_pure_uninitialize(void);
 static VALUE fole_s_ole_uninitialize(VALUE self);
 static VALUE fole_initialize(int argc, VALUE *argv, VALUE self);
 static VALUE hash2named_arg(VALUE pair, struct oleparam* pOp);
@@ -1204,7 +1211,7 @@ void https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L1211
 ole_uninitialize(void)
 {
     OleUninitialize();
-    g_ole_initialized = FALSE;
+    g_ole_initialized_set(FALSE);
 }
 
 static void
@@ -1217,13 +1224,8 @@ ole_initialize(void) https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L1224
         if(FAILED(hr)) {
             ole_raise(hr, rb_eRuntimeError, "fail: OLE initialize");
         }
-        g_ole_initialized = TRUE;
-        /*
-         * In some situation, OleUninitialize does not work fine. ;-<
-         */
-        /*
-        atexit((void (*)(void))ole_uninitialize);
-        */
+        g_ole_initialized_set(TRUE);
+
         hr = CoRegisterMessageFilter(&imessage_filter, &previous_filter);
         if(FAILED(hr)) {
             previous_filter = NULL;
@@ -3141,27 +3143,11 @@ fole_s_create_guid(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L3143
  * You must not use thease method.
  */
 
-static void
-ole_pure_initialize(void)
-{
-    HRESULT hr;
-    hr = OleInitialize(NULL);
-    if(FAILED(hr)) {
-        ole_raise(hr, rb_eRuntimeError, "fail: OLE initialize");
-    }
-}
-
-static void
-ole_pure_uninitialize(void)
-{
-    OleUninitialize();
-}
-
 /* :nodoc */
 static VALUE
 fole_s_ole_initialize(VALUE self)
 {
-    ole_pure_initialize();
+    ole_initialize();
     return Qnil;
 }
 
@@ -3169,7 +3155,7 @@ fole_s_ole_initialize(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L3155
 static VALUE
 fole_s_ole_uninitialize(VALUE self)
 {
-    ole_pure_uninitialize();
+    ole_uninitialize();
     return Qnil;
 }
 
@@ -9080,6 +9066,7 @@ free_enc2cp(void) https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L9066
 void
 Init_win32ole(void)
 {
+    g_ole_initialized_init();
     ary_ole_event = rb_ary_new();
     rb_gc_register_mark_object(ary_ole_event);
     id_events = rb_intern("events");
Index: ext/win32ole/extconf.rb
===================================================================
--- ext/win32ole/extconf.rb	(revision 38866)
+++ ext/win32ole/extconf.rb	(revision 38867)
@@ -23,6 +23,14 @@ def create_win32ole_makefile https://github.com/ruby/ruby/blob/trunk/ext/win32ole/extconf.rb#L23
     unless have_type("IMultiLanguage2", "mlang.h")
       have_type("IMultiLanguage", "mlang.h")
     end
+    spec = nil
+    checking_for('thread_specific', '%s') do
+      spec = %w[__declspec(thread) __thread].find {|th|
+        try_compile("#{th} int foo;", "", :werror => true)
+      }
+      spec or 'no'
+    end
+    $defs << "-DRB_THREAD_SPECIFIC=#{spec}" if spec
     create_makefile("win32ole")
   end
 end

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]