mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
merge revision(s) 17827,17846:17848:
* gc.c: add rb_during_gc(). based on a patch from arton <artonx AT yahoo.co.jp> at [ruby-dev:35313]. * intern.h: ditto. * ext/win32ole/win32ole.c: avoid creating Ruby object during GC. thanks to arton <artonx AT yahoo.co.jp>. [ruby-dev:35313] * ext/win32ole/tests: add test_win32ole_event.rb, remove testOLEEVENT.rb * ext/win32ole/tests/testWIN32OLE.rb(test_convert_bignum): fix test. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8_6@17924 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
b777233e49
commit
7d110cc79c
9 changed files with 275 additions and 95 deletions
18
ChangeLog
18
ChangeLog
|
@ -1,3 +1,21 @@
|
|||
Mon Jul 7 12:07:28 2008 Masaki Suketa <masaki.suketa@nifty.ne.jp>
|
||||
|
||||
* ext/win32ole/win32ole.c: avoid creating Ruby object during
|
||||
GC. thanks to arton <artonx AT yahoo.co.jp>. [ruby-dev:35313]
|
||||
|
||||
* ext/win32ole/tests: add test_win32ole_event.rb, remove
|
||||
testOLEEVENT.rb
|
||||
|
||||
* ext/win32ole/tests/testWIN32OLE.rb(test_convert_bignum):
|
||||
fix test.
|
||||
|
||||
Mon Jul 7 12:07:28 2008 Masaki Suketa <masaki.suketa@nifty.ne.jp>
|
||||
|
||||
* gc.c: add rb_during_gc(). based on a patch from arton <artonx AT
|
||||
yahoo.co.jp> at [ruby-dev:35313].
|
||||
|
||||
* intern.h: ditto.
|
||||
|
||||
Thu Jul 3 17:15:04 2008 URABE Shyouhei <shyouhei@ruby-lang.org>
|
||||
|
||||
* win32/win32.c: revert r17290, requested by NAKAMURA Usaku
|
||||
|
|
|
@ -1,91 +0,0 @@
|
|||
require 'rubyunit'
|
||||
require 'win32ole'
|
||||
|
||||
class TestWIN32OLE_EVENT < RUNIT::TestCase
|
||||
def setup
|
||||
@excel = WIN32OLE.new("Excel.Application")
|
||||
@excel.visible = true
|
||||
@event = ""
|
||||
@event2 = ""
|
||||
end
|
||||
def test_on_event
|
||||
book = @excel.workbooks.Add
|
||||
value = ""
|
||||
begin
|
||||
ev = WIN32OLE_EVENT.new(book, 'WorkbookEvents')
|
||||
ev.on_event('SheetChange'){|arg1, arg2|
|
||||
begin
|
||||
value = arg1.value
|
||||
rescue
|
||||
value = $!.message
|
||||
end
|
||||
}
|
||||
book.Worksheets(1).Range("A1").value = "OK"
|
||||
ensure
|
||||
book.saved = true
|
||||
end
|
||||
assert_equal("OK", value)
|
||||
end
|
||||
|
||||
def handler1
|
||||
@event += "handler1"
|
||||
end
|
||||
def handler2
|
||||
@event += "handler2"
|
||||
end
|
||||
|
||||
def handler3
|
||||
@event += "handler3"
|
||||
end
|
||||
|
||||
def test_on_event2
|
||||
book = @excel.workbooks.Add
|
||||
begin
|
||||
ev = WIN32OLE_EVENT.new(book, 'WorkbookEvents')
|
||||
ev.on_event('SheetChange'){|arg1, arg2|
|
||||
handler1
|
||||
}
|
||||
ev.on_event('SheetChange'){|arg1, arg2|
|
||||
handler2
|
||||
}
|
||||
book.Worksheets(1).Range("A1").value = "OK"
|
||||
ensure
|
||||
book.saved = true
|
||||
end
|
||||
assert_equal("handler2", @event)
|
||||
end
|
||||
|
||||
def test_on_event3
|
||||
book = @excel.workbooks.Add
|
||||
begin
|
||||
ev = WIN32OLE_EVENT.new(book, 'WorkbookEvents')
|
||||
ev.on_event{ handler1 }
|
||||
ev.on_event{ handler2 }
|
||||
book.Worksheets(1).Range("A1").value = "OK"
|
||||
ensure
|
||||
book.saved = true
|
||||
end
|
||||
assert_equal("handler2", @event)
|
||||
end
|
||||
|
||||
def test_on_event4
|
||||
book = @excel.workbooks.Add
|
||||
begin
|
||||
ev = WIN32OLE_EVENT.new(book, 'WorkbookEvents')
|
||||
ev.on_event{ handler1 }
|
||||
ev.on_event{ handler2 }
|
||||
ev.on_event('SheetChange'){|arg1, arg2| handler3 }
|
||||
book.Worksheets(1).Range("A1").value = "OK"
|
||||
ensure
|
||||
book.saved = true
|
||||
end
|
||||
assert_equal("handler3", @event)
|
||||
end
|
||||
|
||||
def teardown
|
||||
@excel.quit
|
||||
@excel = nil
|
||||
GC.start
|
||||
end
|
||||
end
|
||||
|
|
@ -156,7 +156,8 @@ class TestWin32OLE < RUNIT::TestCase
|
|||
sheet.range("A3").value = "=A1*10 + 9"
|
||||
assert_equal(9999999999, sheet.range("A2").value)
|
||||
assert_equal(9999999999, sheet.range("A3").value)
|
||||
|
||||
sheet.range("A4").value = "2008/03/04"
|
||||
assert_equal("2008/03/04 00:00:00", sheet.range("A4").value)
|
||||
ensure
|
||||
book.saved = true
|
||||
end
|
||||
|
|
133
ext/win32ole/tests/test_win32ole_event.rb
Normal file
133
ext/win32ole/tests/test_win32ole_event.rb
Normal file
|
@ -0,0 +1,133 @@
|
|||
begin
|
||||
require 'win32ole'
|
||||
rescue LoadError
|
||||
end
|
||||
require 'test/unit'
|
||||
|
||||
if defined?(WIN32OLE_EVENT)
|
||||
class TestWIN32OLE_EVENT < Test::Unit::TestCase
|
||||
def create_temp_html
|
||||
fso = WIN32OLE.new('Scripting.FileSystemObject')
|
||||
dummy_file = fso.GetTempName + ".html"
|
||||
cfolder = fso.getFolder(".")
|
||||
f = cfolder.CreateTextFile(dummy_file)
|
||||
f.writeLine("<html><body>This is test HTML file for Win32OLE.</body></html>")
|
||||
f.close
|
||||
dummy_path = cfolder.path + "\\" + dummy_file
|
||||
dummy_path
|
||||
end
|
||||
|
||||
def setup
|
||||
@ie = WIN32OLE.new("InternetExplorer.Application")
|
||||
@ie.visible = true
|
||||
@event = ""
|
||||
@event2 = ""
|
||||
@event3 = ""
|
||||
@f = create_temp_html
|
||||
end
|
||||
|
||||
def default_handler(event, *args)
|
||||
@event += event
|
||||
end
|
||||
|
||||
def test_on_event
|
||||
ev = WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents')
|
||||
ev.on_event {|*args| default_handler(*args)}
|
||||
@ie.navigate("file:///#{@f}")
|
||||
while @ie.busy
|
||||
WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents')
|
||||
GC.start
|
||||
sleep 0.1
|
||||
end
|
||||
assert_match(/BeforeNavigate/, @event)
|
||||
assert_match(/NavigateComplete/, @event)
|
||||
end
|
||||
|
||||
def test_on_event2
|
||||
ev = WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents')
|
||||
ev.on_event('BeforeNavigate') {|*args| handler1}
|
||||
ev.on_event('BeforeNavigate') {|*args| handler2}
|
||||
@ie.navigate("file:///#{@f}")
|
||||
while @ie.busy
|
||||
sleep 0.1
|
||||
end
|
||||
assert_equal("handler2", @event2)
|
||||
end
|
||||
|
||||
def test_on_event3
|
||||
ev = WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents')
|
||||
ev.on_event {|*args| handler1}
|
||||
ev.on_event {|*args| handler2}
|
||||
@ie.navigate("file:///#{@f}")
|
||||
while @ie.busy
|
||||
sleep 0.1
|
||||
end
|
||||
assert_equal("handler2", @event2)
|
||||
end
|
||||
|
||||
def test_on_event4
|
||||
ev = WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents')
|
||||
ev.on_event{|*args| handler1}
|
||||
ev.on_event{|*args| handler2}
|
||||
ev.on_event('NavigateComplete'){|*args| handler3(*args)}
|
||||
@ie.navigate("file:///#{@f}")
|
||||
while @ie.busy
|
||||
sleep 0.1
|
||||
end
|
||||
assert(@event3!="")
|
||||
assert("handler2", @event2)
|
||||
end
|
||||
|
||||
def test_on_event5
|
||||
ev = WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents')
|
||||
ev.on_event {|*args| default_handler(*args)}
|
||||
ev.on_event('NavigateComplete'){|*args| handler3(*args)}
|
||||
@ie.navigate("file:///#{@f}")
|
||||
while @ie.busy
|
||||
sleep 0.1
|
||||
end
|
||||
assert_match(/BeforeNavigate/, @event)
|
||||
assert(/NavigateComplete/ !~ @event)
|
||||
assert(@event!="")
|
||||
end
|
||||
|
||||
def test_unadvise
|
||||
ev = WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents')
|
||||
ev.on_event {|*args| default_handler(*args)}
|
||||
@ie.navigate("file:///#{@f}")
|
||||
while @ie.busy
|
||||
sleep 0.1
|
||||
end
|
||||
assert_match(/BeforeNavigate/, @event)
|
||||
ev.unadvise
|
||||
@event = ""
|
||||
@ie.navigate("file:///#{@f}")
|
||||
while @ie.busy
|
||||
sleep 0.1
|
||||
end
|
||||
assert_equal("", @event);
|
||||
assert_raise(WIN32OLERuntimeError) {
|
||||
ev.on_event {|*args| default_handler(*args)}
|
||||
}
|
||||
end
|
||||
|
||||
def handler1
|
||||
@event2 = "handler1"
|
||||
end
|
||||
|
||||
def handler2
|
||||
@event2 = "handler2"
|
||||
end
|
||||
|
||||
def handler3(url)
|
||||
@event3 += url
|
||||
end
|
||||
|
||||
def teardown
|
||||
@ie.quit
|
||||
@ie = nil
|
||||
File.unlink(@f)
|
||||
GC.start
|
||||
end
|
||||
end
|
||||
end
|
|
@ -12,4 +12,5 @@ require "testNIL2VTEMPTY"
|
|||
require "test_ole_methods.rb"
|
||||
require "test_propertyputref.rb"
|
||||
require "test_word.rb"
|
||||
require "test_win32ole_event.rb"
|
||||
# require "testOLEEVENT"
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include <varargs.h>
|
||||
#define va_init_list(a,b) va_start(a)
|
||||
#endif
|
||||
|
||||
#include <objidl.h>
|
||||
|
||||
#define DOUT fprintf(stderr,"[%d]\n",__LINE__)
|
||||
#define DOUTS(x) fprintf(stderr,"[%d]:" #x "=%s\n",__LINE__,x)
|
||||
|
@ -79,7 +79,7 @@
|
|||
|
||||
#define WC2VSTR(x) ole_wc2vstr((x), TRUE)
|
||||
|
||||
#define WIN32OLE_VERSION "0.7.5"
|
||||
#define WIN32OLE_VERSION "0.7.6"
|
||||
|
||||
typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX)
|
||||
(REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*);
|
||||
|
@ -157,6 +157,9 @@ static VALUE com_hash;
|
|||
static IDispatchVtbl com_vtbl;
|
||||
static UINT cWIN32OLE_cp = CP_ACP;
|
||||
static VARTYPE g_nil_to = VT_ERROR;
|
||||
static IMessageFilterVtbl message_filter;
|
||||
static IMessageFilter imessage_filter = { &message_filter };
|
||||
static IMessageFilter* previous_filter;
|
||||
|
||||
struct oledata {
|
||||
IDispatch *pDispatch;
|
||||
|
@ -203,6 +206,101 @@ static char *ole_wc2mb(LPWSTR);
|
|||
static VALUE ole_variant2val(VARIANT*);
|
||||
static void ole_val2variant(VALUE, VARIANT*);
|
||||
|
||||
static HRESULT (STDMETHODCALLTYPE mf_QueryInterface)(
|
||||
IMessageFilter __RPC_FAR * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
|
||||
{
|
||||
if (MEMCMP(riid, &IID_IUnknown, GUID, 1) == 0
|
||||
|| MEMCMP(riid, &IID_IMessageFilter, GUID, 1) == 0)
|
||||
{
|
||||
*ppvObject = &message_filter;
|
||||
return S_OK;
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG (STDMETHODCALLTYPE mf_AddRef)(
|
||||
IMessageFilter __RPC_FAR * This)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static ULONG (STDMETHODCALLTYPE mf_Release)(
|
||||
IMessageFilter __RPC_FAR * This)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static DWORD (STDMETHODCALLTYPE mf_HandleInComingCall)(
|
||||
IMessageFilter __RPC_FAR * pThis,
|
||||
DWORD dwCallType, //Type of incoming call
|
||||
HTASK threadIDCaller, //Task handle calling this task
|
||||
DWORD dwTickCount, //Elapsed tick count
|
||||
LPINTERFACEINFO lpInterfaceInfo //Pointer to INTERFACEINFO structure
|
||||
)
|
||||
{
|
||||
#ifdef DEBUG_MESSAGEFILTER
|
||||
printf("incoming %08X, %08X, %d\n", dwCallType, threadIDCaller, dwTickCount);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
switch (dwCallType)
|
||||
{
|
||||
case CALLTYPE_ASYNC:
|
||||
case CALLTYPE_TOPLEVEL_CALLPENDING:
|
||||
case CALLTYPE_ASYNC_CALLPENDING:
|
||||
if (rb_during_gc()) {
|
||||
return SERVERCALL_RETRYLATER;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (previous_filter) {
|
||||
return previous_filter->lpVtbl->HandleInComingCall(previous_filter,
|
||||
dwCallType,
|
||||
threadIDCaller,
|
||||
dwTickCount,
|
||||
lpInterfaceInfo);
|
||||
}
|
||||
return SERVERCALL_ISHANDLED;
|
||||
}
|
||||
|
||||
static DWORD (STDMETHODCALLTYPE mf_RetryRejectedCall)(
|
||||
IMessageFilter* pThis,
|
||||
HTASK threadIDCallee, //Server task handle
|
||||
DWORD dwTickCount, //Elapsed tick count
|
||||
DWORD dwRejectType //Returned rejection message
|
||||
)
|
||||
{
|
||||
if (previous_filter) {
|
||||
return previous_filter->lpVtbl->RetryRejectedCall(previous_filter,
|
||||
threadIDCallee,
|
||||
dwTickCount,
|
||||
dwRejectType);
|
||||
}
|
||||
return 1000;
|
||||
}
|
||||
|
||||
static DWORD (STDMETHODCALLTYPE mf_MessagePending)(
|
||||
IMessageFilter* pThis,
|
||||
HTASK threadIDCallee, //Called applications task handle
|
||||
DWORD dwTickCount, //Elapsed tick count
|
||||
DWORD dwPendingType //Call type
|
||||
)
|
||||
{
|
||||
if (rb_during_gc()) {
|
||||
return PENDINGMSG_WAITNOPROCESS;
|
||||
}
|
||||
if (previous_filter) {
|
||||
return previous_filter->lpVtbl->MessagePending(previous_filter,
|
||||
threadIDCallee,
|
||||
dwTickCount,
|
||||
dwPendingType);
|
||||
}
|
||||
return PENDINGMSG_WAITNOPROCESS;
|
||||
}
|
||||
|
||||
typedef struct _Win32OLEIDispatch
|
||||
{
|
||||
IDispatch dispatch;
|
||||
|
@ -625,6 +723,11 @@ ole_initialize()
|
|||
/*
|
||||
atexit((void (*)(void))ole_uninitialize);
|
||||
*/
|
||||
hr = CoRegisterMessageFilter(&imessage_filter, &previous_filter);
|
||||
if(FAILED(hr)) {
|
||||
previous_filter = NULL;
|
||||
ole_raise(hr, rb_eRuntimeError, "fail: install OLE MessageFilter");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6135,6 +6238,14 @@ Init_win32ole()
|
|||
com_vtbl.GetTypeInfo = GetTypeInfo;
|
||||
com_vtbl.GetIDsOfNames = GetIDsOfNames;
|
||||
com_vtbl.Invoke = Invoke;
|
||||
|
||||
message_filter.QueryInterface = mf_QueryInterface;
|
||||
message_filter.AddRef = mf_AddRef;
|
||||
message_filter.Release = mf_Release;
|
||||
message_filter.HandleInComingCall = mf_HandleInComingCall;
|
||||
message_filter.RetryRejectedCall = mf_RetryRejectedCall;
|
||||
message_filter.MessagePending = mf_MessagePending;
|
||||
|
||||
com_hash = Data_Wrap_Struct(rb_cData, rb_mark_hash, st_free_table, st_init_numtable());
|
||||
|
||||
cWIN32OLE = rb_define_class("WIN32OLE", rb_cObject);
|
||||
|
|
6
gc.c
6
gc.c
|
@ -373,6 +373,12 @@ add_heap()
|
|||
}
|
||||
#define RANY(o) ((RVALUE*)(o))
|
||||
|
||||
int
|
||||
rb_during_gc()
|
||||
{
|
||||
return during_gc;
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_newobj()
|
||||
{
|
||||
|
|
1
intern.h
1
intern.h
|
@ -239,6 +239,7 @@ VALUE rb_file_directory_p _((VALUE,VALUE));
|
|||
NORETURN(void rb_memerror __((void)));
|
||||
int ruby_stack_check _((void));
|
||||
int ruby_stack_length _((VALUE**));
|
||||
int rb_during_gc _((void));
|
||||
char *rb_source_filename _((const char*));
|
||||
void rb_gc_mark_locations _((VALUE*, VALUE*));
|
||||
void rb_mark_tbl _((struct st_table*));
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define RUBY_RELEASE_DATE "2008-07-07"
|
||||
#define RUBY_VERSION_CODE 186
|
||||
#define RUBY_RELEASE_CODE 20080707
|
||||
#define RUBY_PATCHLEVEL 266
|
||||
#define RUBY_PATCHLEVEL 267
|
||||
|
||||
#define RUBY_VERSION_MAJOR 1
|
||||
#define RUBY_VERSION_MINOR 8
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue