Heesob Park
2008-Jul-21 02:49 UTC
[Win32utils-devel] Patch for Callback [win32utils-Bugs-21275]
Hi, Here is a patch for callback support: --- api.c.org 2008-07-21 11:30:55.000000000 +0900 +++ api.c 2008-07-21 11:29:49.000000000 +0900 @@ -470,16 +470,18 @@ DWORD params[1]; } PARAM; -static VALUE ActiveCallback; +static VALUE CallbackTable = Qnil; -DWORD CallbackFunction(PARAM param) +DWORD CallbackFunction(void* fptr,PARAM param) { VALUE v_proto, v_return, v_proc, v_retval; VALUE argv[16]; int i, argc; char *a_proto; char *a_return; + VALUE ActiveCallback; + ActiveCallback = rb_hash_aref(CallbackTable,INT2NUM((DWORD)fptr)); if(!NIL_P(ActiveCallback)){ v_proto = rb_iv_get(ActiveCallback, "@prototype"); a_proto = RSTRING(v_proto)->ptr; @@ -547,6 +549,43 @@ return 0; } +DWORD CallbackFunction1(PARAM param) +{ + return CallbackFunction(CallbackFunction1,param); +} +DWORD CallbackFunction2(PARAM param) +{ + return CallbackFunction(CallbackFunction2,param); +} +DWORD CallbackFunction3(PARAM param) +{ + return CallbackFunction(CallbackFunction3,param); +} +DWORD CallbackFunction4(PARAM param) +{ + return CallbackFunction(CallbackFunction4,param); +} +DWORD CallbackFunction5(PARAM param) +{ + return CallbackFunction(CallbackFunction5,param); +} +DWORD CallbackFunction6(PARAM param) +{ + return CallbackFunction(CallbackFunction6,param); +} +DWORD CallbackFunction7(PARAM param) +{ + return CallbackFunction(CallbackFunction7,param); +} +DWORD CallbackFunction8(PARAM param) +{ + return CallbackFunction(CallbackFunction8,param); +} + +static void *CallbackArray[] = {CallbackFunction1,CallbackFunction2, + CallbackFunction3,CallbackFunction4,CallbackFunction5,CallbackFunction6, + CallbackFunction7,CallbackFunction8}; + /* * call-seq: * Win32::API#call(arg1, arg2, ...) @@ -563,7 +602,7 @@ VALUE v_proto, v_args, v_arg, v_return; Win32API* ptr; unsigned long return_value; - int i = 0; + int i,j; struct{ unsigned long params[16]; @@ -618,8 +657,17 @@ } break; case _T_CALLBACK: - ActiveCallback = v_arg; - param.params[i] = (LPARAM)CallbackFunction; + if(CallbackTable==Qnil) CallbackTable = rb_hash_new(); + for(j=0;j<8;j++) { + if(rb_hash_aref(CallbackTable,INT2NUM((DWORD)CallbackArray[j]))==Qnil) { + param.params[i] = (LPARAM)CallbackArray[j]; + rb_hash_aset(CallbackTable,INT2NUM((DWORD)CallbackArray[j]),v_arg); + break; + } + if(j==7) { + rb_raise(rb_eArgError,"Callback function table overflow"); + } + } break; I''m not sure this will fix segfault in test suite, but it will fix multiple callback handling problem. Here is test code require ''win32/api'' include Win32 api_ew = API.new(''EnumWindows'', ''KP'', ''L'', ''user32'') api_gwt = API.new(''GetWindowText'', ''LPI'', ''I'', ''user32'') callback1 = API::Callback.new(''LP'', ''I''){ |handle, param| buf = "\0" * 200 p "CALLBACK1" api_gwt.call(handle, buf, 200); buf.index(param).nil? ? true : false } callback2 = API::Callback.new(''LP'', ''I''){ |handle, param| buf = "\0" * 200 p "CALLBACK2" api_gwt.call(handle, buf, 200); buf.index(param).nil? ? true : false } a = Thread.new { api_ew.call(callback1, ''UEDIT32'') } b = Thread.new { api_ew.call(callback2, ''UEDIT32'') } a.join b.join Regards, Park Heesob
Berger, Daniel
2008-Jul-21 14:21 UTC
[Win32utils-devel] Patch for Callback [win32utils-Bugs-21275]
Hi Park,> -----Original Message----- > From: win32utils-devel-bounces at rubyforge.org > [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of > Heesob Park > Sent: Sunday, July 20, 2008 8:49 PM > To: Development and ideas for win32utils projects > Subject: [Win32utils-devel] Patch for Callback [win32utils-Bugs-21275] > > Hi, > > Here is a patch for callback support: > > --- api.c.org 2008-07-21 11:30:55.000000000 +0900 > +++ api.c 2008-07-21 11:29:49.000000000 +0900 > @@ -470,16 +470,18 @@ > DWORD params[1]; > } PARAM; > > -static VALUE ActiveCallback; > +static VALUE CallbackTable = Qnil; > > -DWORD CallbackFunction(PARAM param) > +DWORD CallbackFunction(void* fptr,PARAM param) > { > VALUE v_proto, v_return, v_proc, v_retval; > VALUE argv[16]; > int i, argc; > char *a_proto; > char *a_return; > + VALUE ActiveCallback; > > + ActiveCallback = > rb_hash_aref(CallbackTable,INT2NUM((DWORD)fptr)); > if(!NIL_P(ActiveCallback)){ > v_proto = rb_iv_get(ActiveCallback, "@prototype"); > a_proto = RSTRING(v_proto)->ptr; @@ -547,6 +549,43 @@ > return 0; > } > > +DWORD CallbackFunction1(PARAM param) > +{ > + return CallbackFunction(CallbackFunction1,param); > +} > +DWORD CallbackFunction2(PARAM param) > +{ > + return CallbackFunction(CallbackFunction2,param); > +} > +DWORD CallbackFunction3(PARAM param) > +{ > + return CallbackFunction(CallbackFunction3,param); > +} > +DWORD CallbackFunction4(PARAM param) > +{ > + return CallbackFunction(CallbackFunction4,param); > +} > +DWORD CallbackFunction5(PARAM param) > +{ > + return CallbackFunction(CallbackFunction5,param); > +} > +DWORD CallbackFunction6(PARAM param) > +{ > + return CallbackFunction(CallbackFunction6,param); > +} > +DWORD CallbackFunction7(PARAM param) > +{ > + return CallbackFunction(CallbackFunction7,param); > +} > +DWORD CallbackFunction8(PARAM param) > +{ > + return CallbackFunction(CallbackFunction8,param); > +} > + > +static void *CallbackArray[] = {CallbackFunction1,CallbackFunction2, > + > CallbackFunction3,CallbackFunction4,CallbackFunction5,Callback > Function6, > + CallbackFunction7,CallbackFunction8}; > + > /* > * call-seq: > * Win32::API#call(arg1, arg2, ...) > @@ -563,7 +602,7 @@ > VALUE v_proto, v_args, v_arg, v_return; > Win32API* ptr; > unsigned long return_value; > - int i = 0; > + int i,j; > > struct{ > unsigned long params[16]; > @@ -618,8 +657,17 @@ > } > break; > case _T_CALLBACK: > - ActiveCallback = v_arg; > - param.params[i] = (LPARAM)CallbackFunction; > + if(CallbackTable==Qnil) CallbackTable = > rb_hash_new(); > + for(j=0;j<8;j++) { > + > if(rb_hash_aref(CallbackTable,INT2NUM((DWORD)CallbackArray[j]))==Qnil) > { > + param.params[i] = (LPARAM)CallbackArray[j]; > + > rb_hash_aset(CallbackTable,INT2NUM((DWORD)CallbackArray[j]),v_arg); > + break; > + } > + if(j==7) { > + rb_raise(rb_eArgError,"Callback function table > overflow"); > + } > + } > break;Hi Park Thanks for this. However, I''m wondering if we have to hard code an 8 callback limit. Can''t we dynamically add callbacks to the CallbackArray[] as needed? If we need to use a struct to store additional information, and store an array of those structs internally, that''s fine.> I''m not sure this will fix segfault in test suite, but it > will fix multiple callback handling problem. > Here is test code > > require ''win32/api'' > include Win32 > > api_ew = API.new(''EnumWindows'', ''KP'', ''L'', ''user32'') > api_gwt = API.new(''GetWindowText'', ''LPI'', ''I'', ''user32'') > > callback1 = API::Callback.new(''LP'', ''I''){ |handle, param| > buf = "\0" * 200 > p "CALLBACK1" > api_gwt.call(handle, buf, 200); > buf.index(param).nil? ? true : false > } > callback2 = API::Callback.new(''LP'', ''I''){ |handle, param| > buf = "\0" * 200 > p "CALLBACK2" > api_gwt.call(handle, buf, 200); > buf.index(param).nil? ? true : false > } > > a = Thread.new { > api_ew.call(callback1, ''UEDIT32'') > } > b = Thread.new { > api_ew.call(callback2, ''UEDIT32'') > } > a.join > b.joinThanks, I''ll create some tests modelled on this. Regards, Dan This communication is the property of Qwest and may contain confidential or privileged information. Unauthorized use of this communication is strictly prohibited and may be unlawful. If you have received this communication in error, please immediately notify the sender by reply e-mail and destroy all copies of the communication and any attachments.
Park Heesob
2008-Jul-21 14:38 UTC
[Win32utils-devel] Patch for Callback [win32utils-Bugs-21275]
Hi, ----- Original Message ----- From: "Berger, Daniel" <Daniel.Berger at qwest.com> To: "Development and ideas for win32utils projects" <win32utils-devel at rubyforge.org> Sent: Monday, July 21, 2008 11:21 PM Subject: Re: [Win32utils-devel] Patch for Callback [win32utils-Bugs-21275]> Hi Park, > >> -----Original Message----- >> From: win32utils-devel-bounces at rubyforge.org >> [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of >> Heesob Park >> Sent: Sunday, July 20, 2008 8:49 PM >> To: Development and ideas for win32utils projects >> Subject: [Win32utils-devel] Patch for Callback [win32utils-Bugs-21275] >> >> Hi, >> >> Here is a patch for callback support: >> >> --- api.c.org 2008-07-21 11:30:55.000000000 +0900 >> +++ api.c 2008-07-21 11:29:49.000000000 +0900 >> @@ -470,16 +470,18 @@ >> DWORD params[1]; >> } PARAM; >> >> -static VALUE ActiveCallback; >> +static VALUE CallbackTable = Qnil; >> >> -DWORD CallbackFunction(PARAM param) >> +DWORD CallbackFunction(void* fptr,PARAM param) >> { >> VALUE v_proto, v_return, v_proc, v_retval; >> VALUE argv[16]; >> int i, argc; >> char *a_proto; >> char *a_return; >> + VALUE ActiveCallback; >> >> + ActiveCallback >> rb_hash_aref(CallbackTable,INT2NUM((DWORD)fptr)); >> if(!NIL_P(ActiveCallback)){ >> v_proto = rb_iv_get(ActiveCallback, "@prototype"); >> a_proto = RSTRING(v_proto)->ptr; @@ -547,6 +549,43 @@ >> return 0; >> } >> >> +DWORD CallbackFunction1(PARAM param) >> +{ >> + return CallbackFunction(CallbackFunction1,param); >> +} >> +DWORD CallbackFunction2(PARAM param) >> +{ >> + return CallbackFunction(CallbackFunction2,param); >> +} >> +DWORD CallbackFunction3(PARAM param) >> +{ >> + return CallbackFunction(CallbackFunction3,param); >> +} >> +DWORD CallbackFunction4(PARAM param) >> +{ >> + return CallbackFunction(CallbackFunction4,param); >> +} >> +DWORD CallbackFunction5(PARAM param) >> +{ >> + return CallbackFunction(CallbackFunction5,param); >> +} >> +DWORD CallbackFunction6(PARAM param) >> +{ >> + return CallbackFunction(CallbackFunction6,param); >> +} >> +DWORD CallbackFunction7(PARAM param) >> +{ >> + return CallbackFunction(CallbackFunction7,param); >> +} >> +DWORD CallbackFunction8(PARAM param) >> +{ >> + return CallbackFunction(CallbackFunction8,param); >> +} >> + >> +static void *CallbackArray[] = {CallbackFunction1,CallbackFunction2, >> + >> CallbackFunction3,CallbackFunction4,CallbackFunction5,Callback >> Function6, >> + CallbackFunction7,CallbackFunction8}; >> + >> /* >> * call-seq: >> * Win32::API#call(arg1, arg2, ...) >> @@ -563,7 +602,7 @@ >> VALUE v_proto, v_args, v_arg, v_return; >> Win32API* ptr; >> unsigned long return_value; >> - int i = 0; >> + int i,j; >> >> struct{ >> unsigned long params[16]; >> @@ -618,8 +657,17 @@ >> } >> break; >> case _T_CALLBACK: >> - ActiveCallback = v_arg; >> - param.params[i] = (LPARAM)CallbackFunction; >> + if(CallbackTable==Qnil) CallbackTable >> rb_hash_new(); >> + for(j=0;j<8;j++) { >> + >> if(rb_hash_aref(CallbackTable,INT2NUM((DWORD)CallbackArray[j]))==Qnil) >> { >> + param.params[i] = (LPARAM)CallbackArray[j]; >> + >> rb_hash_aset(CallbackTable,INT2NUM((DWORD)CallbackArray[j]),v_arg); >> + break; >> + } >> + if(j==7) { >> + rb_raise(rb_eArgError,"Callback function table >> overflow"); >> + } >> + } >> break; > > Hi Park > > Thanks for this. However, I''m wondering if we have to hard code an 8 > callback limit. Can''t we dynamically add callbacks to the > CallbackArray[] as needed? If we need to use a struct to store > additional information, and store an array of those structs internally, > that''s fine. >That is what I want to do. But that is not easy. Would you try it a little more? Regards, Park Heesob