Hi, Ruby 1.8.6-p114 built with VC++ 8 win32-service 0.6.1 (also built with VC++ 8) Windows XP Pro SP 2 I''m having trouble getting even this simple daemon to work. I can''t even get it to log an error to the file. Any ideas? # demon.rb begin LOG_FILE = "C:\\demon_test.log" LOG_HANDLE = File.open(LOG_FILE, ''a'') STDIN.close STDERR.reopen(LOG_HANDLE) STDOUT.reopen(LOG_HANDLE) require ''win32/daemon'' include Win32 class Daemon def service_main while running? sleep 3 puts "service is running" end end def service_stop exit! end end Daemon.mainloop rescue Exception => err puts "ERROR: #{err}" puts puts "Our Daemon blowed up: " + err.backtrace.join("\n") raise ensure LOG_HANDLE.close if LOG_HANDLE && !LOG_HANDLE.closed? end # demo_ctl.rb require ''win32/service'' require ''rbconfig'' include Config include Win32 case ARGV.first.chomp when ''install'' # Some path handling to deal with spaces and slashes path = File.join(CONFIG[''bindir''], ''ruby.exe'') + '' '' path += ''"'' + File.expand_path(''demon.rb'') + ''"'' path = path.tr("/", "\\") Service.create(''DemoService'', nil, :display_name => ''DemoService'', :service_type => Service::WIN32_OWN_PROCESS, :description => ''Demo Service'', :binary_path_name => path, :service_start_name => ''my_domain\my_userid'', :password => ''my_password'' ) puts "Service created" when ''stop'' Service.stop(''DemoService'') puts "Service stopped" when ''start'' Service.start(''DemoService'') puts "Service started" when ''uninstall'' Service.delete(''DemoService'') puts "Service uninstalled" else STDERR.puts "Valid options are ''install'', ''uninstall'', ''stop'' and ''start''" end In other news, it doesn''t seem to like the default service_type. If I don''t explicitly pass it an option the CreateService() call at line 332 will die. Maybe I should remove "interactive" as part of the default. 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.
2008/10/31 Berger, Daniel <Daniel.Berger at qwest.com>:> Hi, > > Ruby 1.8.6-p114 built with VC++ 8 > win32-service 0.6.1 (also built with VC++ 8) > Windows XP Pro SP 2 > > I''m having trouble getting even this simple daemon to work. I can''t even > get it to log an error to the file. Any ideas? > > # demon.rb > begin > LOG_FILE = "C:\\demon_test.log" > LOG_HANDLE = File.open(LOG_FILE, ''a'') > > STDIN.close > STDERR.reopen(LOG_HANDLE) > STDOUT.reopen(LOG_HANDLE) > > require ''win32/daemon'' > include Win32 > > class Daemon > def service_main > while running? > sleep 3 > puts "service is running" > end > end > > def service_stop > exit! > end > end > > Daemon.mainloop > rescue Exception => err > puts "ERROR: #{err}" > puts > puts "Our Daemon blowed up: " + err.backtrace.join("\n") > raise > ensure > LOG_HANDLE.close if LOG_HANDLE && !LOG_HANDLE.closed? > end > > # demo_ctl.rb > require ''win32/service'' > require ''rbconfig'' > include Config > include Win32 > > case ARGV.first.chomp > when ''install'' > # Some path handling to deal with spaces and slashes > path = File.join(CONFIG[''bindir''], ''ruby.exe'') + '' '' > path += ''"'' + File.expand_path(''demon.rb'') + ''"'' > path = path.tr("/", "\\") > > Service.create(''DemoService'', nil, > :display_name => ''DemoService'', > :service_type => Service::WIN32_OWN_PROCESS, > :description => ''Demo Service'', > :binary_path_name => path, > :service_start_name => ''my_domain\my_userid'', > :password => ''my_password'' > ) > puts "Service created" > when ''stop'' > Service.stop(''DemoService'') > puts "Service stopped" > when ''start'' > Service.start(''DemoService'') > puts "Service started" > when ''uninstall'' > Service.delete(''DemoService'') > puts "Service uninstalled" > else > STDERR.puts "Valid options are ''install'', ''uninstall'', ''stop'' and > ''start''" > end > > In other news, it doesn''t seem to like the default service_type. If I > don''t explicitly pass it an option the CreateService() call at line 332 > will die. Maybe I should remove "interactive" as part of the default. > > Regards, > > Dan >In my test, I found two problems in the above demon.rb . First, your environment may has RUBYOPT and raised following error. ruby: no such file to load -- ubygems (LoadError) I have workarounded by modifing "RUBYOPT" to "RUBYOPTX" in ruby.c #755. Second, STDIN.close in demon.rb raise error. In my thought, STDIN.close is just a meaningless code. Regards, Park Heesob
> -----Original Message----- > From: win32utils-devel-bounces at rubyforge.org > [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of > Heesob Park > Sent: Friday, October 31, 2008 4:52 AM > To: Development and ideas for win32utils projects > Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem > > 2008/10/31 Berger, Daniel <Daniel.Berger at qwest.com>: > > Hi, > > > > Ruby 1.8.6-p114 built with VC++ 8 > > win32-service 0.6.1 (also built with VC++ 8) Windows XP Pro SP 2 > > > > I''m having trouble getting even this simple daemon to work. I can''t > > even get it to log an error to the file. Any ideas? > > > > # demon.rb > > begin > > LOG_FILE = "C:\\demon_test.log" > > LOG_HANDLE = File.open(LOG_FILE, ''a'') > > > > STDIN.close > > STDERR.reopen(LOG_HANDLE) > > STDOUT.reopen(LOG_HANDLE) > > > > require ''win32/daemon'' > > include Win32 > > > > class Daemon > > def service_main > > while running? > > sleep 3 > > puts "service is running" > > end > > end > > > > def service_stop > > exit! > > end > > end > > > > Daemon.mainloop > > rescue Exception => err > > puts "ERROR: #{err}" > > puts > > puts "Our Daemon blowed up: " + err.backtrace.join("\n") > > raise > > ensure > > LOG_HANDLE.close if LOG_HANDLE && !LOG_HANDLE.closed? > > end > > > > # demo_ctl.rb > > require ''win32/service'' > > require ''rbconfig'' > > include Config > > include Win32 > > > > case ARGV.first.chomp > > when ''install'' > > # Some path handling to deal with spaces and slashes > > path = File.join(CONFIG[''bindir''], ''ruby.exe'') + '' '' > > path += ''"'' + File.expand_path(''demon.rb'') + ''"'' > > path = path.tr("/", "\\") > > > > Service.create(''DemoService'', nil, > > :display_name => ''DemoService'', > > :service_type => Service::WIN32_OWN_PROCESS, > > :description => ''Demo Service'', > > :binary_path_name => path, > > :service_start_name => ''my_domain\my_userid'', > > :password => ''my_password'' > > ) > > puts "Service created" > > when ''stop'' > > Service.stop(''DemoService'') > > puts "Service stopped" > > when ''start'' > > Service.start(''DemoService'') > > puts "Service started" > > when ''uninstall'' > > Service.delete(''DemoService'') > > puts "Service uninstalled" > > else > > STDERR.puts "Valid options are ''install'', ''uninstall'', > ''stop'' and > > ''start''" > > end > > > > In other news, it doesn''t seem to like the default > service_type. If I > > don''t explicitly pass it an option the CreateService() call at line > > 332 will die. Maybe I should remove "interactive" as part > of the default. > > > > Regards, > > > > Dan > > > In my test, I found two problems in the above demon.rb . > First, your environment may has RUBYOPT and raised following error. > ruby: no such file to load -- ubygems (LoadError)I tried unsetting RUBYOPT on the command line and setting it to nil from within the daemon itself, but it still didn''t work. I also don''t get any output to the log file.> I have workarounded by modifing "RUBYOPT" to "RUBYOPTX" in > ruby.c #755.Eep! That seems a bit extreme. I wouldn''t think we would need to.> Second, STDIN.close in demon.rb raise error. > In my thought, STDIN.close is just a meaningless code.Yeah, it was just me experimenting mostly. Removing it didn''t help, though. On a related note, I''ve been thinking that perhaps Daemon.new should take an optional log file. If present, have STDERR and STDOUT reopen on that file instead of NUL. It would be the users job to properly close the handle in the service_stop method, although perhaps we could setup a finalizer. Does that sound like a good idea? Anyway, still no luck with running the Daemon itself. Now that we have callbacks working better in win32-api, I''m hoping to revisit the pure Ruby Win32::Daemon class again. :) 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.
----- Original Message ----- From: "Berger, Daniel" <Daniel.Berger at qwest.com> To: "Development and ideas for win32utils projects" <win32utils-devel at rubyforge.org> Sent: Saturday, November 01, 2008 1:12 AM Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem>> ><snip>>> In my test, I found two problems in the above demon.rb . >> First, your environment may has RUBYOPT and raised following error. >> ruby: no such file to load -- ubygems (LoadError) > > I tried unsetting RUBYOPT on the command line and setting it to nil from > within the daemon itself, but it still didn''t work. I also don''t get any > output to the log file. > >> I have workarounded by modifing "RUBYOPT" to "RUBYOPTX" in >> ruby.c #755. > > Eep! That seems a bit extreme. I wouldn''t think we would need to. >Did you try it? You must have log file of size 0 when the log file does not exist. It is a proof of passing RUBYOPT barrier.>> Second, STDIN.close in demon.rb raise error. >> In my thought, STDIN.close is just a meaningless code. > > Yeah, it was just me experimenting mostly. Removing it didn''t help, > though. >In Demon''s rescue part, try LOG_HANDLE.print instead of puts to print error.> On a related note, I''ve been thinking that perhaps Daemon.new should > take an optional log file. If present, have STDERR and STDOUT reopen on > that file instead of NUL. It would be the users job to properly close > the handle in the service_stop method, although perhaps we could setup a > finalizer. > > Does that sound like a good idea? >It seems a good idea. Another possible option is using the win32-eventlog instead of the log file.> Anyway, still no luck with running the Daemon itself. Now that we have > callbacks working better in win32-api, I''m hoping to revisit the pure > Ruby Win32::Daemon class again. :) >It would be better to have pure Ruby version. But in this case, I have success to start Daemon. You should find out why it fails to work. :) Regards, Park Heesob
Hi, 2008/11/1 Berger, Daniel <Daniel.Berger at qwest.com>:> > Anyway, still no luck with running the Daemon itself. Now that we have > callbacks working better in win32-api, I''m hoping to revisit the pure > Ruby Win32::Daemon class again. :) >I struggled with the callback and service control whole weekend :) I made the pure Ruby Win32::Daemon class as you expected. Here are two patches and two ruby code. First patch is trivial for callback support. Second patch is a little messy. I added address attribute to callback class. As you know, Win32 thread is not working well with Ruby. So I implemented pure Ruby version as two separate processes without thread. The daemon.rb and daemon0.rb must be in the same folder. Some code cleanup and adding close handle code are required. I think the startup argument notification need to reform. I tried mmap and pipe but both failed with segment fault. Patch for windows-pr/lib/windows/service.rb --- service.rb.bak 2008-11-03 00:24:35.000000000 +0900 +++ service.rb 2008-11-03 00:24:35.000000000 +0900 @@ -128,7 +128,7 @@ API.new(''QueryServiceLockStatus'', ''LPLP'', ''B'', ''advapi32'') API.new(''QueryServiceStatus'', ''LP'', ''B'', ''advapi32'') API.new(''QueryServiceStatusEx'', ''LLPLP'', ''B'', ''advapi32'') - API.new(''RegisterServiceCtrlHandler'', ''PL'', ''L'', ''advapi32'') + API.new(''RegisterServiceCtrlHandler'', ''PK'', ''L'', ''advapi32'') API.new(''RegisterServiceCtrlHandlerEx'', ''PPP'', ''L'', ''advapi32'') API.new(''SetServiceBits'', ''LLII'', ''B'', ''advapi32'') API.new(''SetServiceStatus'', ''LP'', ''B'', ''advapi32'') Patch for win32-api/ext/win32/api.c --- api.c.old 2008-11-03 00:25:46.000000000 +0900 +++ api.c 2008-11-03 00:25:05.000000000 +0900 @@ -12,6 +12,7 @@ #define _T_STRING 5 VALUE cAPIError, cCallbackError; +static VALUE ActiveCallback = Qnil; typedef struct { HANDLE library; @@ -109,6 +110,7 @@ */ static VALUE callback_init(int argc, VALUE* argv, VALUE self) { + extern void *CallbackTable[]; VALUE v_proto, v_return, v_proc; int i; @@ -131,6 +133,8 @@ rb_iv_set(self, "@function", v_proc); rb_iv_set(self, "@prototype", v_proto); rb_iv_set(self, "@return_type", v_return); + rb_iv_set(self, "@address", ULONG2NUM((LPARAM)CallbackTable[RSTRING(v_proto) + ActiveCallback = self; return self; } @@ -473,7 +477,6 @@ DWORD params[16]; } CALLPARAM; -static VALUE ActiveCallback; DWORD CallbackFunction(CALLPARAM param) { @@ -811,6 +814,7 @@ rb_define_attr(cCallback, "return_type", 1, 0); /* The numeric address of the function pointer */ + rb_define_attr(cCallback, "address", 1, 0); rb_define_attr(cFunction, "address", 1, 0); /* Constants */ ======================= start daemon0.rb ======================require ''windows/service'' require ''windows/thread'' require ''windows/synchronize'' require ''windows/handle'' require ''windows/error'' require ''windows/msvcrt/buffer'' require ''windows/msvcrt/string'' require ''win32/api'' include Windows::Service include Windows::Thread include Windows::Synchronize include Windows::Handle include Windows::Error include Windows::MSVCRT::Buffer include Windows::MSVCRT::String # Wraps SetServiceStatus. def set_the_service_statue(curr_state, exit_code, check_point, wait_hint) service_status = 0.chr * 28 # sizeof(SERVICE_STATUS) # Disable control requests until the service is started. if curr_state == SERVICE_START_PENDING val = 0 else val = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN end service_status[8,4] = [val].pack(''L'') # Initialize service_status struct service_status[0,4] = [SERVICE_WIN32_OWN_PROCESS].pack(''L'') service_status[4,4] = [curr_state].pack(''L'') service_status[12,4] = [exit_code].pack(''L'') service_status[20,4] = [check_point].pack(''L'') service_status[24,4] = [wait_hint].pack(''L'') service_state = curr_state # Send status of the service to the Service Controller. unless SetServiceStatus(@status_handle, service_status) SetEvent(@stop_event) end end begin @arg_event = OpenEvent(EVENT_ALL_ACCESS, 0, "arg_event_#{ARGV[0]}") if @arg_event == 0 raise Error, get_last_error end @end_event = OpenEvent(EVENT_ALL_ACCESS, 0, "end_event_#{ARGV[0]}") if @end_event == 0 raise Error, get_last_error end @stop_event = OpenEvent(EVENT_ALL_ACCESS, 0, "stop_event_#{ARGV[0]}") if @stop_event == 0 raise Error, get_last_error end @pause_event = OpenEvent(EVENT_ALL_ACCESS, 0, "pause_event_#{ARGV[0]}") if @pause_event == 0 raise Error, get_last_error end @resume_event = OpenEvent(EVENT_ALL_ACCESS, 0, "resume_event_#{ARGV[0]}") if @resume_event == 0 raise Error, get_last_error end service_ctrl = Win32::API::Callback.new(''L'', ''V'') do |ctrl_code| state = SERVICE_RUNNING case ctrl_code when SERVICE_CONTROL_STOP state = SERVICE_STOP_PENDING when SERVICE_CONTROL_PAUSE state = SERVICE_PAUSED SetEvent(@pause_event) when SERVICE_CONTROL_CONTINUE state = SERVICE_RUNNING SetEvent(@resume_event) end # Set the status of the service. set_the_service_statue(state, NO_ERROR, 0, 0) # Tell service_main thread to stop. if [SERVICE_CONTROL_STOP].include?(ctrl_code) wait_result = WaitForSingleObject(@end_event, INFINITE) if wait_result != WAIT_OBJECT_0 set_the_service_statue(SERVICE_STOPPED,GetLastError(),0,0) else set_the_service_statue(SERVICE_STOPPED,NO_ERROR,0,0) end SetEvent(@stop_event) sleep 3 end end svc_main = Win32::API::Callback.new(''LL'', ''I'') do |argc, lpszargv| argv = [] argc.times do |i| ptr = 0.chr * 4 buf = 0.chr * 256 memcpy(ptr,lpszargv+i*4,4) strcpy(buf,ptr.unpack(''L'').first) argv << buf.strip end service_name = argv[0] f = File.new(ENV[''TEMP'']+"\\daemon#{ARGV[0]}","w") f.print(argv.join('';'')) f.close SetEvent(@arg_event) # Register the service ctrl handler. @status_handle = RegisterServiceCtrlHandler( service_name,service_ctrl ) # No service to stop, no service handle to notify, nothing to do # but exit at this point. return false if @status_handle == 0 #The service has started. set_the_service_statue(SERVICE_RUNNING, NO_ERROR, 0, 0) true end dispatch_table = [""].pack(''p'') + [svc_main.address].pack(''L'') + "\0"*8 if(!StartServiceCtrlDispatcher(dispatch_table)) File.open("c:\\test.txt","a+") {|f| f.puts("StartServiceCtrlDispatcher Fail") } end rescue Exception => err File.open("c:\\test.txt","a+") {|f| f.puts(err.inspect) } end ======================= end daemon0.rb ====================== ======================= start daemon.rb ======================require ''windows/service'' require ''windows/thread'' require ''windows/synchronize'' require ''windows/handle'' require ''windows/error'' require ''windows/msvcrt/buffer'' require ''windows/msvcrt/string'' require ''win32/api'' require ''win32/process'' require ''win32/service'' module Win32 class Daemon class Error < StandardError; end include Windows::Service include Windows::Thread include Windows::Synchronize include Windows::Handle include Windows::Error include Windows::MSVCRT::Buffer include Windows::MSVCRT::String VERSION = ''0.6.1'' # The Daemon has received a resume signal, but is not yet running CONTINUE_PENDING = 0x00000005 # The Daemon is in an idle state IDLE = 0 # The Daemon is stopped, i.e. not running STOPPED = 0x00000001 # The Daemon has received a start signal, but is not yet running START_PENDING = 0x00000002 # The Daemon has received a sto signal but is not yet stopped. STOP_PENDING = 0x00000003 # The Daemon is running normally RUNNING = 0x00000004 # The Daemon has received a pause signal, but is not yet paused PAUSE_PENDING = 0x00000006 # The Daemon is in a paused state PAUSED = 0x00000007 # The current state of the service, e.g. RUNNING, PAUSED, etc. attr_reader :state def initialize @critical_section = [0].pack(''L'') @service_state = nil @start_event = nil @stop_event = nil @control_code = 0 @event_hooks = {} @status_handle = 0 end def mainloop @arg_event = CreateEvent(0, 0, 0, "arg_event_#{Process.pid}") if @arg_event == 0 raise Error, get_last_error end @end_event = CreateEvent(0, 0, 0, "end_event_#{Process.pid}") if @end_event == 0 raise Error, get_last_error end @stop_event = CreateEvent(0, 0, 0, "stop_event_#{Process.pid}") if @stop_event == 0 raise Error, get_last_error end @pause_event = CreateEvent(0, 0, 0, "pause_event_#{Process.pid}") if @pause_event == 0 raise Error, get_last_error end @resume_event = CreateEvent(0, 0, 0, "resume_event_#{Process.pid}") if @resume_event == 0 raise Error, get_last_error end service_init() if defined?(service_init) tmpfile = ENV[''TEMP'']+"\\daemon#{Process.pid}" File.delete(tmpfile) if File.exist?(tmpfile) ruby = File.join(CONFIG[''bindir''], ''ruby '').tr(''/'', ''\\'') path = File.dirname(__FILE__) + "//daemon0.rb #{Process.pid}" Process.create( :app_name => ruby + path, :creation_flags => Process::CREATE_NO_WINDOW ) wait_result = WaitForSingleObject(@arg_event, INFINITE) if wait_result == WAIT_FAILED error = ''WaitForSingleObject() failed: '' + get_last_error raise Error, error elsif File.exist?(tmpfile) && File.size(tmpfile)>0 f = File.open(tmpfile) data = f.gets f.close else data = '''' end data = data || '''' argv = data.split('';'') @service_name = argv[0] handles = [@stop_event, at pause_event, at resume_event] t = Thread.new { while(true) do wait = WaitForMultipleObjects( handles.size, handles.pack(''L*''), 0, 10 ) if wait >= WAIT_OBJECT_0 && wait <= WAIT_OBJECT_0 + handles.size - 1 index = wait - WAIT_OBJECT_0 case handles[index] when @stop_event service_stop() if defined?(service_stop) return when @pause_event service_pause() if defined?(service_pause) when @resume_event service_resume() if defined?(service_resume) end end end } service_main(argv) if defined?(service_main) SetEvent(@end_event) t.join end def running? true if [RUNNING,START_PENDING].include?(state) end def state case Win32::Service.status(@service_name).current_state when ''running'' return RUNNING when ''start pending'' return START_PENDING when ''stopped'' return STOPPED when ''paused'' return PAUSED end return 0 end # Shortcut for Daemon.new#mainloop def self.mainloop new.mainloop end end end ======================= end daemon.rb ====================== Regards, Park Heesob
Hi,> -----Original Message----- > From: win32utils-devel-bounces at rubyforge.org > [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of > Heesob Park > Sent: Sunday, November 02, 2008 8:52 AM > To: Development and ideas for win32utils projects > Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem > > Hi, > > 2008/11/1 Berger, Daniel <Daniel.Berger at qwest.com>: > > > > Anyway, still no luck with running the Daemon itself. Now > that we have > > callbacks working better in win32-api, I''m hoping to > revisit the pure > > Ruby Win32::Daemon class again. :) > > > I struggled with the callback and service control whole > weekend :) I made the pure Ruby Win32::Daemon class as you expected. > Here are two patches and two ruby code.Oh, excellent!> First patch is trivial for callback support. > Second patch is a little messy. I added address attribute to > callback class. > > As you know, Win32 thread is not working well with Ruby. > So I implemented pure Ruby version as two separate processes > without thread. > The daemon.rb and daemon0.rb must be in the same folder. > Some code cleanup and adding close handle code are required. > I think the startup argument notification need to reform. > I tried mmap and pipe but both failed with segment fault. > > Patch for windows-pr/lib/windows/service.rb > --- service.rb.bak 2008-11-03 00:24:35.000000000 +0900 > +++ service.rb 2008-11-03 00:24:35.000000000 +0900 > @@ -128,7 +128,7 @@ > API.new(''QueryServiceLockStatus'', ''LPLP'', ''B'', ''advapi32'') > API.new(''QueryServiceStatus'', ''LP'', ''B'', ''advapi32'') > API.new(''QueryServiceStatusEx'', ''LLPLP'', ''B'', ''advapi32'') > - API.new(''RegisterServiceCtrlHandler'', ''PL'', ''L'', ''advapi32'') > + API.new(''RegisterServiceCtrlHandler'', ''PK'', ''L'', ''advapi32'') > API.new(''RegisterServiceCtrlHandlerEx'', ''PPP'', ''L'', ''advapi32'') > API.new(''SetServiceBits'', ''LLII'', ''B'', ''advapi32'') > API.new(''SetServiceStatus'', ''LP'', ''B'', ''advapi32'')Ok, I''ve updated both RegisterServiceCtrlHandler and RegisterServiceCtrlHandlerEx in CVS. That update will be part of the 0.9.6 release of windows-pr.> Patch for win32-api/ext/win32/api.c > --- api.c.old 2008-11-03 00:25:46.000000000 +0900 > +++ api.c 2008-11-03 00:25:05.000000000 +0900 > @@ -12,6 +12,7 @@ > #define _T_STRING 5 > > VALUE cAPIError, cCallbackError; > +static VALUE ActiveCallback = Qnil; > > typedef struct { > HANDLE library; > @@ -109,6 +110,7 @@ > */ > static VALUE callback_init(int argc, VALUE* argv, VALUE self) { > + extern void *CallbackTable[]; > VALUE v_proto, v_return, v_proc; > int i; > > @@ -131,6 +133,8 @@ > rb_iv_set(self, "@function", v_proc); > rb_iv_set(self, "@prototype", v_proto); > rb_iv_set(self, "@return_type", v_return); > + rb_iv_set(self, "@address", > ULONG2NUM((LPARAM)CallbackTable[RSTRING(v_proto)Whoops. I think something got cut off here. What should that be?> + ActiveCallback = self; > > return self; > } > @@ -473,7 +477,6 @@ > DWORD params[16]; > } CALLPARAM; > > -static VALUE ActiveCallback; > > DWORD CallbackFunction(CALLPARAM param) { @@ -811,6 +814,7 @@ > rb_define_attr(cCallback, "return_type", 1, 0); > > /* The numeric address of the function pointer */ > + rb_define_attr(cCallback, "address", 1, 0); > rb_define_attr(cFunction, "address", 1, 0); > > /* Constants */<snip the pure Ruby stuff> Looks good. It may be a little while before I can get back to it, since I''m getting swamped at work. Many thanks! Dan PS - Maybe it''s time to revisit http://rubyforge.org/tracker/index.php?func=detail&aid=16627&group_id=85 &atid=413, too. 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.
2008/11/4 Berger, Daniel <Daniel.Berger at qwest.com>:> Hi, > >> -----Original Message----- >> From: win32utils-devel-bounces at rubyforge.org >> [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of >> Heesob Park >> Sent: Sunday, November 02, 2008 8:52 AM >> To: Development and ideas for win32utils projects >> Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem >> >> Hi, >> >> 2008/11/1 Berger, Daniel <Daniel.Berger at qwest.com>: >> > >> > Anyway, still no luck with running the Daemon itself. Now >> that we have >> > callbacks working better in win32-api, I''m hoping to >> revisit the pure >> > Ruby Win32::Daemon class again. :) >> > >> I struggled with the callback and service control whole >> weekend :) I made the pure Ruby Win32::Daemon class as you expected. >> Here are two patches and two ruby code. > > Oh, excellent! > >> First patch is trivial for callback support. >> Second patch is a little messy. I added address attribute to >> callback class. >> >> As you know, Win32 thread is not working well with Ruby. >> So I implemented pure Ruby version as two separate processes >> without thread. >> The daemon.rb and daemon0.rb must be in the same folder. >> Some code cleanup and adding close handle code are required. >> I think the startup argument notification need to reform. >> I tried mmap and pipe but both failed with segment fault. >> >> Patch for windows-pr/lib/windows/service.rb >> --- service.rb.bak 2008-11-03 00:24:35.000000000 +0900 >> +++ service.rb 2008-11-03 00:24:35.000000000 +0900 >> @@ -128,7 +128,7 @@ >> API.new(''QueryServiceLockStatus'', ''LPLP'', ''B'', ''advapi32'') >> API.new(''QueryServiceStatus'', ''LP'', ''B'', ''advapi32'') >> API.new(''QueryServiceStatusEx'', ''LLPLP'', ''B'', ''advapi32'') >> - API.new(''RegisterServiceCtrlHandler'', ''PL'', ''L'', ''advapi32'') >> + API.new(''RegisterServiceCtrlHandler'', ''PK'', ''L'', ''advapi32'') >> API.new(''RegisterServiceCtrlHandlerEx'', ''PPP'', ''L'', ''advapi32'') >> API.new(''SetServiceBits'', ''LLII'', ''B'', ''advapi32'') >> API.new(''SetServiceStatus'', ''LP'', ''B'', ''advapi32'') > > Ok, I''ve updated both RegisterServiceCtrlHandler and > RegisterServiceCtrlHandlerEx in CVS. That update will be part of the > 0.9.6 release of windows-pr. > >> Patch for win32-api/ext/win32/api.c >> --- api.c.old 2008-11-03 00:25:46.000000000 +0900 >> +++ api.c 2008-11-03 00:25:05.000000000 +0900 >> @@ -12,6 +12,7 @@ >> #define _T_STRING 5 >> >> VALUE cAPIError, cCallbackError; >> +static VALUE ActiveCallback = Qnil; >> >> typedef struct { >> HANDLE library; >> @@ -109,6 +110,7 @@ >> */ >> static VALUE callback_init(int argc, VALUE* argv, VALUE self) { >> + extern void *CallbackTable[]; >> VALUE v_proto, v_return, v_proc; >> int i; >> >> @@ -131,6 +133,8 @@ >> rb_iv_set(self, "@function", v_proc); >> rb_iv_set(self, "@prototype", v_proto); >> rb_iv_set(self, "@return_type", v_return); >> + rb_iv_set(self, "@address", >> ULONG2NUM((LPARAM)CallbackTable[RSTRING(v_proto) > > Whoops. I think something got cut off here. What should that be? >+ rb_iv_set(self, "@address", ULONG2NUM((LPARAM)CallbackTable[RSTRING(v_proto) Should be one line.>> + ActiveCallback = self; >> >> return self; >> } >> @@ -473,7 +477,6 @@ >> DWORD params[16]; >> } CALLPARAM; >> >> -static VALUE ActiveCallback; >> >> DWORD CallbackFunction(CALLPARAM param) { @@ -811,6 +814,7 @@ >> rb_define_attr(cCallback, "return_type", 1, 0); >> >> /* The numeric address of the function pointer */ >> + rb_define_attr(cCallback, "address", 1, 0); >> rb_define_attr(cFunction, "address", 1, 0); >> >> /* Constants */ > > <snip the pure Ruby stuff> > > Looks good. It may be a little while before I can get back to it, since > I''m getting swamped at work. >> > PS - Maybe it''s time to revisit > http://rubyforge.org/tracker/index.php?func=detail&aid=16627&group_id=85 > &atid=413, too. >Yes. The inter process communication with the socket might a good choice. I will test it. Regards, Park Heesob
Hi, <snip>> > PS - Maybe it''s time to revisit > > > http://rubyforge.org/tracker/index.php?func=detail&aid=16627&group_id> > 85 > > &atid=413, too. > > > Yes. The inter process communication with the socket might a > good choice. > I will test it.Another thing to consider, now that Jruby''s FFI is now bundled with Jruby itself and supports callbacks, is whether or not we want to declare Jruby as the preferred platform for creating Ruby services since it supports native threads. Of course, this means finishing the port of win32-api. :) 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.
----- Original Message ----- From: "Berger, Daniel" <Daniel.Berger at qwest.com> To: "Development and ideas for win32utils projects" <win32utils-devel at rubyforge.org> Sent: Tuesday, November 04, 2008 10:38 PM Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem> Hi, > > <snip> > >> > PS - Maybe it''s time to revisit >> > >> http://rubyforge.org/tracker/index.php?func=detail&aid=16627&group_id>> > 85 >> > &atid=413, too. >> > >> Yes. The inter process communication with the socket might a >> good choice. >> I will test it. > > Another thing to consider, now that Jruby''s FFI is now bundled with > Jruby itself and supports callbacks, is whether or not we want to > declare Jruby as the preferred platform for creating Ruby services since > it supports native threads. > > Of course, this means finishing the port of win32-api. :) >I consider that there are three ways to go to support of the Windows native threads. 1. Use Jruby 2. Use Ruby 1.9.x 3. Implement the Sapphire :) If you dislike Ruby''s dl library, using libffi(http://sourceware.org/libffi/) is also possible. I have read Programming in Lua recently and I am playing with Lua nowadays. I think Lua is a powerful and potential language. Lua uses alien module which is based on the libffi. Regards, Park Heesob
> -----Original Message----- > From: win32utils-devel-bounces at rubyforge.org > [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of > Park Heesob > Sent: Tuesday, November 04, 2008 7:23 AM > To: Development and ideas for win32utils projects > Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem > > > ----- Original Message ----- > From: "Berger, Daniel" <Daniel.Berger at qwest.com> > To: "Development and ideas for win32utils projects" > <win32utils-devel at rubyforge.org> > Sent: Tuesday, November 04, 2008 10:38 PM > Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem > > > > Hi, > > > > <snip> > > > >> > PS - Maybe it''s time to revisit > >> > > >> > http://rubyforge.org/tracker/index.php?func=detail&aid=16627&group_id> >> > 85 > >> > &atid=413, too. > >> > > >> Yes. The inter process communication with the socket might a > >> good choice. > >> I will test it. > > > > Another thing to consider, now that Jruby''s FFI is now bundled with > > Jruby itself and supports callbacks, is whether or not we want to > > declare Jruby as the preferred platform for creating Ruby > services since > > it supports native threads. > > > > Of course, this means finishing the port of win32-api. :) > > > I consider that there are three ways to go to support of the > Windows native > threads. > > 1. Use Jruby > 2. Use Ruby 1.9.x > 3. Implement the Sapphire :) > > If you dislike Ruby''s dl library, using > libffi(http://sourceware.org/libffi/) is also possible.Well, FFI is supposed to be universal now, though I can''t get it to build on Windows at the moment. So it would be the same code for MRI (1.8 and 1.9) and Jruby.> I have read Programming in Lua recently and I am playing with > Lua nowadays. > I think Lua is a powerful and potential language. > Lua uses alien module which is based on the libffi.I''ve heard good things about Lua, but mostly I''ve only ever heard of it being used for games. 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.
On Tue, Nov 4, 2008 at 1:21 PM, Berger, Daniel <Daniel.Berger at qwest.com> wrote:> > >> -----Original Message----- >> From: win32utils-devel-bounces at rubyforge.org >> [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of >> Park Heesob >> Sent: Tuesday, November 04, 2008 7:23 AM >> To: Development and ideas for win32utils projects >> Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem >> >> >> ----- Original Message ----- >> From: "Berger, Daniel" <Daniel.Berger at qwest.com> >> To: "Development and ideas for win32utils projects" >> <win32utils-devel at rubyforge.org> >> Sent: Tuesday, November 04, 2008 10:38 PM >> Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem >> >> >> > Hi, >> > >> > <snip> >> > >> >> > PS - Maybe it''s time to revisit >> >> > >> >> >> http://rubyforge.org/tracker/index.php?func=detail&aid=16627&group_id>> >> > 85 >> >> > &atid=413, too. >> >> > >> >> Yes. The inter process communication with the socket might a >> >> good choice. >> >> I will test it. >> > >> > Another thing to consider, now that Jruby''s FFI is now bundled with >> > Jruby itself and supports callbacks, is whether or not we want to >> > declare Jruby as the preferred platform for creating Ruby >> services since >> > it supports native threads. >> > >> > Of course, this means finishing the port of win32-api. :) >> > >> I consider that there are three ways to go to support of the >> Windows native >> threads. >> >> 1. Use Jruby >> 2. Use Ruby 1.9.x >> 3. Implement the Sapphire :) >> >> If you dislike Ruby''s dl library, using >> libffi(http://sourceware.org/libffi/) is also possible. > > Well, FFI is supposed to be universal now, though I can''t get it to > build on Windows at the moment. So it would be the same code for MRI > (1.8 and 1.9) and Jruby. >libffi builds "better" with GCC than with VC* I got libffi built while working with Rubinius, but dunno if the version used is the same (I think it includes some hardcoded stuff in the makefiles).>> I have read Programming in Lua recently and I am playing with >> Lua nowadays. >> I think Lua is a powerful and potential language. >> Lua uses alien module which is based on the libffi. > > I''ve heard good things about Lua, but mostly I''ve only ever heard of it > being used for games. >Lua is awesome, small, fast and easy to integrate to other applications, which AFAIK was the primary goal. -- Luis Lavena AREA 17 - Human beings, who are almost unique in having the ability to learn from the experience of others, are also remarkable for their apparent disinclination to do so. Douglas Adams
2008/11/5 Luis Lavena <luislavena at gmail.com>:> On Tue, Nov 4, 2008 at 1:21 PM, Berger, Daniel <Daniel.Berger at qwest.com> wrote: >> >> >>> -----Original Message----- >>> From: win32utils-devel-bounces at rubyforge.org >>> [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of >>> Park Heesob >>> Sent: Tuesday, November 04, 2008 7:23 AM >>> To: Development and ideas for win32utils projects >>> Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem >>> >>> >>> ----- Original Message ----- >>> From: "Berger, Daniel" <Daniel.Berger at qwest.com> >>> To: "Development and ideas for win32utils projects" >>> <win32utils-devel at rubyforge.org> >>> Sent: Tuesday, November 04, 2008 10:38 PM >>> Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem >>> >>> >>> > Hi, >>> > >>> > <snip> >>> > >>> >> > PS - Maybe it''s time to revisit >>> >> > >>> >> >>> http://rubyforge.org/tracker/index.php?func=detail&aid=16627&group_id>>> >> > 85 >>> >> > &atid=413, too. >>> >> > >>> >> Yes. The inter process communication with the socket might a >>> >> good choice. >>> >> I will test it. >>> > >>> > Another thing to consider, now that Jruby''s FFI is now bundled with >>> > Jruby itself and supports callbacks, is whether or not we want to >>> > declare Jruby as the preferred platform for creating Ruby >>> services since >>> > it supports native threads. >>> > >>> > Of course, this means finishing the port of win32-api. :) >>> > >>> I consider that there are three ways to go to support of the >>> Windows native >>> threads. >>> >>> 1. Use Jruby >>> 2. Use Ruby 1.9.x >>> 3. Implement the Sapphire :) >>> >>> If you dislike Ruby''s dl library, using >>> libffi(http://sourceware.org/libffi/) is also possible. >> >> Well, FFI is supposed to be universal now, though I can''t get it to >> build on Windows at the moment. So it would be the same code for MRI >> (1.8 and 1.9) and Jruby. >> > > libffi builds "better" with GCC than with VC* > > I got libffi built while working with Rubinius, but dunno if the > version used is the same (I think it includes some hardcoded stuff in > the makefiles). >I noticed the FFI 0.1.1 (http://kenai.com/projects/ruby-ffi/pages/Home) is actually the extension library of libffi. There are needs of more work on Windows, but it''s only a matter of time. I feel the end of Win32-API is close at hand and the FFI will unify ruby/DL and Win32-API. Regards, Park Heesob
----- Original Message ----- From: "Berger, Daniel" <Daniel.Berger at qwest.com> To: "Development and ideas for win32utils projects" <win32utils-devel at rubyforge.org> Sent: Tuesday, November 04, 2008 1:23 AM Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem> > PS - Maybe it''s time to revisit > http://rubyforge.org/tracker/index.php?func=detail&aid=16627&group_id=85 > &atid=413, too. >Here is the new version using TCP protocal. ======================= start daemon0.rb ======================require ''windows/service'' require ''windows/thread'' require ''windows/synchronize'' require ''windows/handle'' require ''windows/error'' require ''windows/msvcrt/buffer'' require ''windows/msvcrt/string'' require ''win32/api'' require ''socket'' include Windows::Service include Windows::Thread include Windows::Synchronize include Windows::Handle include Windows::Error include Windows::MSVCRT::Buffer include Windows::MSVCRT::String # Wraps SetServiceStatus. def set_the_service_statue(curr_state, exit_code, check_point, wait_hint) service_status = 0.chr * 28 # sizeof(SERVICE_STATUS) # Disable control requests until the service is started. if curr_state == SERVICE_START_PENDING val = 0 else val = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN end service_status[8,4] = [val].pack(''L'') # Initialize service_status struct service_status[0,4] = [SERVICE_WIN32_OWN_PROCESS].pack(''L'') service_status[4,4] = [curr_state].pack(''L'') service_status[12,4] = [exit_code].pack(''L'') service_status[20,4] = [check_point].pack(''L'') service_status[24,4] = [wait_hint].pack(''L'') service_state = curr_state # Send status of the service to the Service Controller. unless SetServiceStatus(@status_handle, service_status) SetEvent(@stop_event) end end begin @end_event = OpenEvent(EVENT_ALL_ACCESS, 0, "end_event_#{ARGV[0]}") if @end_event == 0 raise Error, get_last_error end @stop_event = OpenEvent(EVENT_ALL_ACCESS, 0, "stop_event_#{ARGV[0]}") if @stop_event == 0 raise Error, get_last_error end @pause_event = OpenEvent(EVENT_ALL_ACCESS, 0, "pause_event_#{ARGV[0]}") if @pause_event == 0 raise Error, get_last_error end @resume_event = OpenEvent(EVENT_ALL_ACCESS, 0, "resume_event_#{ARGV[0]}") if @resume_event == 0 raise Error, get_last_error end service_ctrl = Win32::API::Callback.new(''L'', ''V'') do |ctrl_code| state = SERVICE_RUNNING case ctrl_code when SERVICE_CONTROL_STOP state = SERVICE_STOP_PENDING when SERVICE_CONTROL_PAUSE state = SERVICE_PAUSED SetEvent(@pause_event) when SERVICE_CONTROL_CONTINUE state = SERVICE_RUNNING SetEvent(@resume_event) end # Set the status of the service. set_the_service_statue(state, NO_ERROR, 0, 0) # Tell service_main thread to stop. if [SERVICE_CONTROL_STOP].include?(ctrl_code) wait_result = WaitForSingleObject(@end_event, INFINITE) if wait_result != WAIT_OBJECT_0 set_the_service_statue(SERVICE_STOPPED,GetLastError(),0,0) else set_the_service_statue(SERVICE_STOPPED,NO_ERROR,0,0) end SetEvent(@stop_event) sleep 3 end end svc_main = Win32::API::Callback.new(''LL'', ''I'') do |argc, lpszargv| argv = [] argc.times do |i| ptr = 0.chr * 4 buf = 0.chr * 256 memcpy(ptr,lpszargv+i*4,4) strcpy(buf,ptr.unpack(''L'').first) argv << buf.strip end service_name = argv[0] s = TCPSocket.open(''127.0.0.1'', ARGV[0]) s.write(argv.join('';'')) s.close # Register the service ctrl handler. @status_handle = RegisterServiceCtrlHandler( service_name,service_ctrl ) # No service to stop, no service handle to notify, nothing to do # but exit at this point. return false if @status_handle == 0 #The service has started. set_the_service_statue(SERVICE_RUNNING, NO_ERROR, 0, 0) true end dispatch_table = [""].pack(''p'') + [svc_main.address].pack(''L'') + "\0"*8 if(!StartServiceCtrlDispatcher(dispatch_table)) File.open("c:\\test.txt","a+") {|f| f.puts("StartServiceCtrlDispatcher Fail") } end rescue Exception => err File.open("c:\\test.txt","a+") {|f| f.puts(err.inspect) } end ======================= end daemon0.rb ====================== ======================= start daemon.rb ======================require ''windows/service'' require ''windows/thread'' require ''windows/synchronize'' require ''windows/handle'' require ''windows/error'' require ''windows/msvcrt/buffer'' require ''windows/msvcrt/string'' require ''win32/api'' require ''win32/process'' require ''win32/service'' require ''socket'' module Win32 class Daemon class Error < StandardError; end include Windows::Service include Windows::Thread include Windows::Synchronize include Windows::Handle include Windows::Error include Windows::MSVCRT::Buffer include Windows::MSVCRT::String VERSION = ''0.6.1'' # The Daemon has received a resume signal, but is not yet running CONTINUE_PENDING = 0x00000005 # The Daemon is in an idle state IDLE = 0 # The Daemon is stopped, i.e. not running STOPPED = 0x00000001 # The Daemon has received a start signal, but is not yet running START_PENDING = 0x00000002 # The Daemon has received a sto signal but is not yet stopped. STOP_PENDING = 0x00000003 # The Daemon is running normally RUNNING = 0x00000004 # The Daemon has received a pause signal, but is not yet paused PAUSE_PENDING = 0x00000006 # The Daemon is in a paused state PAUSED = 0x00000007 # The current state of the service, e.g. RUNNING, PAUSED, etc. attr_reader :state def mainloop gs = TCPserver.open(0) @end_event = CreateEvent(0, 0, 0, "end_event_#{gs.addr[1]}") if @end_event == 0 raise Error, get_last_error end @stop_event = CreateEvent(0, 0, 0, "stop_event_#{gs.addr[1]}") if @stop_event == 0 raise Error, get_last_error end @pause_event = CreateEvent(0, 0, 0, "pause_event_#{gs.addr[1]}") if @pause_event == 0 raise Error, get_last_error end @resume_event = CreateEvent(0, 0, 0, "resume_event_#{gs.addr[1]}") if @resume_event == 0 raise Error, get_last_error end service_init() if defined?(service_init) ruby = File.join(CONFIG[''bindir''], ''ruby '').tr(''/'', ''\\'') path = File.dirname(__FILE__) + "//daemon0.rb #{gs.addr[1]}" Process.create( :app_name => ruby + path, :creation_flags => Process::CREATE_NO_WINDOW ) nsock = select([gs]) s = gs.accept data = s.gets s.close data = data || '''' argv = data.split('';'') @service_name = argv[0] handles = [@stop_event, at pause_event, at resume_event] t = Thread.new { while(true) do wait = WaitForMultipleObjects( handles.size, handles.pack(''L*''), 0, 10 ) if wait >= WAIT_OBJECT_0 && wait <= WAIT_OBJECT_0 + handles.size - 1 index = wait - WAIT_OBJECT_0 case handles[index] when @stop_event service_stop() if defined?(service_stop) return when @pause_event service_pause() if defined?(service_pause) when @resume_event service_resume() if defined?(service_resume) end end end } service_main(argv) if defined?(service_main) SetEvent(@end_event) t.join end def running? true if [RUNNING,START_PENDING].include?(state) end def state case Win32::Service.status(@service_name).current_state when ''running'' return RUNNING when ''start pending'' return START_PENDING when ''stopped'' return STOPPED when ''paused'' return PAUSED end return 0 end # Shortcut for Daemon.new#mainloop def self.mainloop new.mainloop end end end ======================= end daemon.rb ====================== Regards, Park Heesob
> -----Original Message----- > From: win32utils-devel-bounces at rubyforge.org > [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of > Park Heesob > Sent: Wednesday, November 05, 2008 8:56 AM > To: Development and ideas for win32utils projects > Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem > > > ----- Original Message ----- > From: "Berger, Daniel" <Daniel.Berger at qwest.com> > To: "Development and ideas for win32utils projects" > <win32utils-devel at rubyforge.org> > Sent: Tuesday, November 04, 2008 1:23 AM > Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem > > > > PS - Maybe it''s time to revisit > > > http://rubyforge.org/tracker/index.php?func=detail&aid=16627&group_id> > 85 > > &atid=413, too. > > > Here is the new version using TCP protocal.<snip> Wow, excellent. Thanks for all your hard work! Do you prefer this implementation to the other one? The _only_ downside I see here is the socket/runtime issue with the one click installer. If we ship this version, I think we must ship our own socket.so, too. That, or we rewrite the socket library using win32-api or ffi, and make that a dependency, but I think that''s a last resort. Anyway, thanks again! 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.
2008/11/6 Berger, Daniel <Daniel.Berger at qwest.com>:> > >> -----Original Message----- >> From: win32utils-devel-bounces at rubyforge.org >> [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of >> Park Heesob >> Sent: Wednesday, November 05, 2008 8:56 AM >> To: Development and ideas for win32utils projects >> Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem >> >> >> ----- Original Message ----- >> From: "Berger, Daniel" <Daniel.Berger at qwest.com> >> To: "Development and ideas for win32utils projects" >> <win32utils-devel at rubyforge.org> >> Sent: Tuesday, November 04, 2008 1:23 AM >> Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem >> > >> > PS - Maybe it''s time to revisit >> > >> http://rubyforge.org/tracker/index.php?func=detail&aid=16627&group_id>> > 85 >> > &atid=413, too. >> > >> Here is the new version using TCP protocal. > > <snip> > > Wow, excellent. Thanks for all your hard work! > > Do you prefer this implementation to the other one? > > The _only_ downside I see here is the socket/runtime issue with the one > click installer. If we ship this version, I think we must ship our own > socket.so, too. That, or we rewrite the socket library using win32-api > or ffi, and make that a dependency, but I think that''s a last resort. >The socket/runtime issue is a ruby-core win32.c issue related with the USE_WINSOCK2 macro. The current quick workaround is running configure.bat without --with-winsock2 option. Is there any special reason One-Click Ruby Installer team built Ruby with --with-winsock2 option? Regards, Park Heesob
On Wed, Nov 5, 2008 at 10:08 PM, Heesob Park <phasis at gmail.com> wrote:> 2008/11/6 Berger, Daniel <Daniel.Berger at qwest.com>: >> >> >>> -----Original Message----- >>> From: win32utils-devel-bounces at rubyforge.org >>> [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of >>> Park Heesob >>> Sent: Wednesday, November 05, 2008 8:56 AM >>> To: Development and ideas for win32utils projects >>> Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem >>> >>> >>> ----- Original Message ----- >>> From: "Berger, Daniel" <Daniel.Berger at qwest.com> >>> To: "Development and ideas for win32utils projects" >>> <win32utils-devel at rubyforge.org> >>> Sent: Tuesday, November 04, 2008 1:23 AM >>> Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem >>> > >>> > PS - Maybe it''s time to revisit >>> > >>> http://rubyforge.org/tracker/index.php?func=detail&aid=16627&group_id>>> > 85 >>> > &atid=413, too. >>> > >>> Here is the new version using TCP protocal. >> >> <snip> >> >> Wow, excellent. Thanks for all your hard work! >> >> Do you prefer this implementation to the other one? >> >> The _only_ downside I see here is the socket/runtime issue with the one >> click installer. If we ship this version, I think we must ship our own >> socket.so, too. That, or we rewrite the socket library using win32-api >> or ffi, and make that a dependency, but I think that''s a last resort. >> > The socket/runtime issue is a ruby-core win32.c issue related with the > USE_WINSOCK2 macro. The current quick workaround is running > configure.bat without --with-winsock2 option. Is there any special > reason One-Click Ruby Installer team built Ruby with --with-winsock2 > option? >Actually the binaries bundled with One-Click Ruby Installer are from japanesse site garbagecollect: http://www.garbagecollect.jp/ruby/mswin32/en/ We don''t have the control over the build or the dependencies and we need to "find" which one was the proper one :-P Another reason we are working on the MinGW version. -- Luis Lavena AREA 17 - Human beings, who are almost unique in having the ability to learn from the experience of others, are also remarkable for their apparent disinclination to do so. Douglas Adams
Hi,> Patch for win32-api/ext/win32/api.c > --- api.c.old 2008-11-03 00:25:46.000000000 +0900 > +++ api.c 2008-11-03 00:25:05.000000000 +0900 > @@ -12,6 +12,7 @@ > #define _T_STRING 5 > > VALUE cAPIError, cCallbackError; > +static VALUE ActiveCallback = Qnil; > > typedef struct { > HANDLE library; > @@ -109,6 +110,7 @@ > */ > static VALUE callback_init(int argc, VALUE* argv, VALUE self) { > + extern void *CallbackTable[]; > VALUE v_proto, v_return, v_proc; > int i; > > @@ -131,6 +133,8 @@ > rb_iv_set(self, "@function", v_proc); > rb_iv_set(self, "@prototype", v_proto); > rb_iv_set(self, "@return_type", v_return); > + rb_iv_set(self, "@address", > ULONG2NUM((LPARAM)CallbackTable[RSTRING(v_proto) > + ActiveCallback = self; > > return self; > } > @@ -473,7 +477,6 @@ > DWORD params[16]; > } CALLPARAM; > > -static VALUE ActiveCallback; > > DWORD CallbackFunction(CALLPARAM param) { @@ -811,6 +814,7 @@ > rb_define_attr(cCallback, "return_type", 1, 0); > > /* The numeric address of the function pointer */ > + rb_define_attr(cCallback, "address", 1, 0); > rb_define_attr(cFunction, "address", 1, 0); > > /* Constants */Park, can you please commit this change? Thanks, 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.
2008/11/6 Berger, Daniel <Daniel.Berger at qwest.com>:> Hi, > >> Patch for win32-api/ext/win32/api.c >> --- api.c.old 2008-11-03 00:25:46.000000000 +0900 >> +++ api.c 2008-11-03 00:25:05.000000000 +0900 >> @@ -12,6 +12,7 @@ >> #define _T_STRING 5 >> >> VALUE cAPIError, cCallbackError; >> +static VALUE ActiveCallback = Qnil; >> >> typedef struct { >> HANDLE library; >> @@ -109,6 +110,7 @@ >> */ >> static VALUE callback_init(int argc, VALUE* argv, VALUE self) { >> + extern void *CallbackTable[]; >> VALUE v_proto, v_return, v_proc; >> int i; >> >> @@ -131,6 +133,8 @@ >> rb_iv_set(self, "@function", v_proc); >> rb_iv_set(self, "@prototype", v_proto); >> rb_iv_set(self, "@return_type", v_return); >> + rb_iv_set(self, "@address", >> ULONG2NUM((LPARAM)CallbackTable[RSTRING(v_proto) >> + ActiveCallback = self; >> >> return self; >> } >> @@ -473,7 +477,6 @@ >> DWORD params[16]; >> } CALLPARAM; >> >> -static VALUE ActiveCallback; >> >> DWORD CallbackFunction(CALLPARAM param) { @@ -811,6 +814,7 @@ >> rb_define_attr(cCallback, "return_type", 1, 0); >> >> /* The numeric address of the function pointer */ >> + rb_define_attr(cCallback, "address", 1, 0); >> rb_define_attr(cFunction, "address", 1, 0); >> >> /* Constants */ > > Park, can you please commit this change? >OK. I did it. Regards, Park Heesob
> -----Original Message----- > From: win32utils-devel-bounces at rubyforge.org > [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of > Heesob Park > Sent: Thursday, November 06, 2008 7:20 AM > To: Development and ideas for win32utils projects > Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem > > 2008/11/6 Berger, Daniel <Daniel.Berger at qwest.com>: > > Hi, > > > >> Patch for win32-api/ext/win32/api.c > >> --- api.c.old 2008-11-03 00:25:46.000000000 +0900 > >> +++ api.c 2008-11-03 00:25:05.000000000 +0900 > >> @@ -12,6 +12,7 @@ > >> #define _T_STRING 5 > >> > >> VALUE cAPIError, cCallbackError; > >> +static VALUE ActiveCallback = Qnil; > >> > >> typedef struct { > >> HANDLE library; > >> @@ -109,6 +110,7 @@ > >> */ > >> static VALUE callback_init(int argc, VALUE* argv, VALUE self) { > >> + extern void *CallbackTable[]; > >> VALUE v_proto, v_return, v_proc; > >> int i; > >> > >> @@ -131,6 +133,8 @@ > >> rb_iv_set(self, "@function", v_proc); > >> rb_iv_set(self, "@prototype", v_proto); > >> rb_iv_set(self, "@return_type", v_return); > >> + rb_iv_set(self, "@address", > >> ULONG2NUM((LPARAM)CallbackTable[RSTRING(v_proto) > >> + ActiveCallback = self; > >> > >> return self; > >> } > >> @@ -473,7 +477,6 @@ > >> DWORD params[16]; > >> } CALLPARAM; > >> > >> -static VALUE ActiveCallback; > >> > >> DWORD CallbackFunction(CALLPARAM param) { @@ -811,6 +814,7 @@ > >> rb_define_attr(cCallback, "return_type", 1, 0); > >> > >> /* The numeric address of the function pointer */ > >> + rb_define_attr(cCallback, "address", 1, 0); > >> rb_define_attr(cFunction, "address", 1, 0); > >> > >> /* Constants */ > > > > Park, can you please commit this change? > > > OK. I did it.Excellent. I wanted you do to do it so I could see what was getting chopped off in my email for line 136: ")->len]));" I figured that was it, but didn''t want to take any chances. I''m not sure if it''s an Outlook formatting issue or what. Anyway, thanks for doing that. 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.
2008/11/6 Berger, Daniel <Daniel.Berger at qwest.com>:> > >> -----Original Message----- >> From: win32utils-devel-bounces at rubyforge.org >> [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of >> Park Heesob >> Sent: Wednesday, November 05, 2008 8:56 AM >> To: Development and ideas for win32utils projects >> Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem >> >> >> ----- Original Message ----- >> From: "Berger, Daniel" <Daniel.Berger at qwest.com> >> To: "Development and ideas for win32utils projects" >> <win32utils-devel at rubyforge.org> >> Sent: Tuesday, November 04, 2008 1:23 AM >> Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem >> > >> > PS - Maybe it''s time to revisit >> > >> http://rubyforge.org/tracker/index.php?func=detail&aid=16627&group_id>> > 85 >> > &atid=413, too. >> > >> Here is the new version using TCP protocal. > > <snip> > > Wow, excellent. Thanks for all your hard work! > > Do you prefer this implementation to the other one? > > The _only_ downside I see here is the socket/runtime issue with the one > click installer. If we ship this version, I think we must ship our own > socket.so, too. That, or we rewrite the socket library using win32-api > or ffi, and make that a dependency, but I think that''s a last resort. > > Anyway, thanks again! >I did reported the socket bug and a patch and the ruby-core accepted the patch. http://redmine.ruby-lang.org/issues/show/714 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8/win32/win32.c?view=log The next binary release will don''t have socket bug any more :) Regards, Park Heesob
Hi, <snip>> I did reported the socket bug and a patch and the ruby-core > accepted the patch. > > http://redmine.ruby-lang.org/issues/show/714 > http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8/win32/win32.c?view=log> > The next binary release will don''t have socket bug any more :)Excellent, thanks! Does this mean you prefer this implementation? 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.
Hi, 2008/11/10 Berger, Daniel <Daniel.Berger at qwest.com>:> Hi, > > <snip> > >> I did reported the socket bug and a patch and the ruby-core >> accepted the patch. >> >> http://redmine.ruby-lang.org/issues/show/714 >> http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8/ > win32/win32.c?view=log >> >> The next binary release will don''t have socket bug any more :) > > Excellent, thanks! > > Does this mean you prefer this implementation? >No, I don''t prefer anything. I don''t mind whichever method if it is stable and reliable. Regards, Park Heesob
Hi, 2008/11/5 Berger, Daniel <Daniel.Berger at qwest.com>:> > >> > >> > Another thing to consider, now that Jruby''s FFI is now bundled with >> > Jruby itself and supports callbacks, is whether or not we want to >> > declare Jruby as the preferred platform for creating Ruby >> services since >> > it supports native threads. >> > >> > Of course, this means finishing the port of win32-api. :) >> > >> I consider that there are three ways to go to support of the >> Windows native >> threads. >> >> 1. Use Jruby >> 2. Use Ruby 1.9.x >> 3. Implement the Sapphire :) >> >> If you dislike Ruby''s dl library, using >> libffi(http://sourceware.org/libffi/) is also possible. > > Well, FFI is supposed to be universal now, though I can''t get it to > build on Windows at the moment. So it would be the same code for MRI > (1.8 and 1.9) and Jruby. >In my thought, the current ruby ffi implementation don''t care of the Windows support. As far as I know, the ffi developers have no definite plan about releasing of Windows binary. If it were built to binary with mingw compiler, It cannot work with Windows API. It uses dlopen,dlsym and dlclose instead of LoadLibrary,GetProcAddress and FreeLibrary. I managed to build MSVC version of ruby ffi-0.2.0 using win32 libffi source ported by the Python''s ctypes library. You can download ctypes at sourceforge [1]. What''s your thought about implementing ruby-ffi windows version? Is it worthwhile or meaningless? At now the callback function support is not working but the others work fine. I succeeded following test code: require ''ffi'' module Foo extend FFI::Library ffi_lib("advapi32.dll") attach_function("GetUserName", "GetUserNameA", [:string, :pointer], :int) end buf = 0.chr * 256 size = [256].pack(''L'') p Foo.GetUserName(buf,size) len = size.unpack(''L'').first puts buf[0,len] [1] http://sourceforge.net/project/showfiles.php?group_id=71702&package_id=71318 Regards, Park Heesob
> -----Original Message----- > From: win32utils-devel-bounces at rubyforge.org > [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of > Heesob Park > Sent: Thursday, January 22, 2009 8:10 PM > To: Development and ideas for win32utils projects > Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem<snip>> > Well, FFI is supposed to be universal now, though I can''t get it to > > build on Windows at the moment. So it would be the same code for MRI > > (1.8 and 1.9) and Jruby. > > > In my thought, the current ruby ffi implementation don''t care > of the Windows support. As far as I know, the ffi developers > have no definite plan about releasing of Windows binary. If > it were built to binary with mingw compiler, It cannot work > with Windows API. It uses dlopen,dlsym and dlclose instead of > LoadLibrary,GetProcAddress and FreeLibrary.That''s unfortunate.> I managed to build MSVC version of ruby ffi-0.2.0 using win32 > libffi source ported by the Python''s ctypes library. You can > download ctypes at sourceforge [1]. > What''s your thought about implementing ruby-ffi windows > version? Is it worthwhile or meaningless?It''s only worthwhile if the other implementations can run it. Otherwise, I don''t see a practical advantage over win32-api. Do you? Also, do you mean that your version requires Python''s ctypes library? Or do you mean you''ve ported it to Ruby? 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.
On 23 Jan 2009, at 03:09, Heesob Park wrote:> Hi, > > 2008/11/5 Berger, Daniel <Daniel.Berger at qwest.com>: >> >> >>>> >>>> Another thing to consider, now that Jruby''s FFI is now bundled with >>>> Jruby itself and supports callbacks, is whether or not we want to >>>> declare Jruby as the preferred platform for creating Ruby >>> services since >>>> it supports native threads. >>>> >>>> Of course, this means finishing the port of win32-api. :) >>>> >>> I consider that there are three ways to go to support of the >>> Windows native >>> threads. >>> >>> 1. Use Jruby >>> 2. Use Ruby 1.9.x >>> 3. Implement the Sapphire :) >>> >>> If you dislike Ruby''s dl library, using >>> libffi(http://sourceware.org/libffi/) is also possible. >> >> Well, FFI is supposed to be universal now, though I can''t get it to >> build on Windows at the moment. So it would be the same code for MRI >> (1.8 and 1.9) and Jruby. >> > In my thought, the current ruby ffi implementation don''t care of the > Windows support. As far as I know, the ffi developers have no definite > plan about releasing of Windows binary. If it were built to binary > with mingw compiler, It cannot work with Windows API. It uses > dlopen,dlsym and dlclose instead of LoadLibrary,GetProcAddress and > FreeLibrary.The current hg repo seems to build under mingw with some patches (removing unused (under win32) functionality), however, I have been unable to get the gem install to work (i need to do some more reading in rake-compiler). Until I have some more time to debug I won''t know much detail on that. iirc most or all of the ffi test suite passes, from a repo build.> I managed to build MSVC version of ruby ffi-0.2.0 using win32 libffi > source ported by the Python''s ctypes library. You can download ctypes > at sourceforge [1]. > What''s your thought about implementing ruby-ffi windows version? Is it > worthwhile or meaningless?FFI is slower, but provides significant implementation flexibility (namely portability). It could be harder to stub out in some cases, for users. A bigger problem with this is that under mingw we don''t get the SEH stuff. GCC doesn''t support it, and by the looks of the various documentation / mailing list messages around, there is no really solid implementation at this point (although this may be old/stale information). From what I can see, it appears that the strongest implementation can be found in the Wine project, but may take a lot of work to get it where ruby would want / need it. This means that _try, _finalize (both used in win32-services / win32- api (i can''t remember which - may be both)) don''t work as expected. My solution to date (using mingw), in order to maintain some semblance of error handling, is to simply gem inst --platform=x86-mswin32-60 win32-services, however this is far from ideal. I am doubtful that simply omitting these lines (_try, _finalize) is a good idea, and more than this, I am not sure there is any way at all to implement them whilst using the FFI.> At now the callback function support is not working but the others > work fine. > > I succeeded following test code: > > require ''ffi'' > module Foo > extend FFI::Library > ffi_lib("advapi32.dll") > attach_function("GetUserName", "GetUserNameA", > [:string, :pointer], :int) > end > > buf = 0.chr * 256 > size = [256].pack(''L'') > p Foo.GetUserName(buf,size) > len = size.unpack(''L'').first > puts buf[0,len] > > > > [1] http://sourceforge.net/project/showfiles.php?group_id=71702&package_id=71318 > > Regards, > > Park Heesob > _______________________________________________ > win32utils-devel mailing list > win32utils-devel at rubyforge.org > http://rubyforge.org/mailman/listinfo/win32utils-devel
2009/1/24 Berger, Daniel <Daniel.Berger at qwest.com>:>> -----Original Message----- >> From: win32utils-devel-bounces at rubyforge.org >> [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of >> Heesob Park >> Sent: Thursday, January 22, 2009 8:10 PM >> To: Development and ideas for win32utils projects >> Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem > > <snip> > >> > Well, FFI is supposed to be universal now, though I can''t get it to >> > build on Windows at the moment. So it would be the same code for MRI >> > (1.8 and 1.9) and Jruby. >> > >> In my thought, the current ruby ffi implementation don''t care >> of the Windows support. As far as I know, the ffi developers >> have no definite plan about releasing of Windows binary. If >> it were built to binary with mingw compiler, It cannot work >> with Windows API. It uses dlopen,dlsym and dlclose instead of >> LoadLibrary,GetProcAddress and FreeLibrary. > > That''s unfortunate. > >> I managed to build MSVC version of ruby ffi-0.2.0 using win32 >> libffi source ported by the Python''s ctypes library. You can >> download ctypes at sourceforge [1]. >> What''s your thought about implementing ruby-ffi windows >> version? Is it worthwhile or meaningless? > > It''s only worthwhile if the other implementations can run it. Otherwise, > I don''t see a practical advantage over win32-api. Do you? >I don''t care of it. I just want to implement win32 version of libffi.> Also, do you mean that your version requires Python''s ctypes library? Or > do you mean you''ve ported it to Ruby? >I have pasted the ctypes libffi win32 folder to ruby-ffi just as Lua did on alien library. At last, I succeeded callback function testing. The patched source code and binary gem is at http://121.78.227.9/ffi-0.2.0/ Regards, Park Heesob
> -----Original Message----- > From: win32utils-devel-bounces at rubyforge.org > [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of > Heesob Park > Sent: Friday, January 23, 2009 3:41 PM > To: Development and ideas for win32utils projects > Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem > > 2009/1/24 Berger, Daniel <Daniel.Berger at qwest.com>: > >> -----Original Message----- > >> From: win32utils-devel-bounces at rubyforge.org > >> [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf > Of Heesob > >> Park > >> Sent: Thursday, January 22, 2009 8:10 PM > >> To: Development and ideas for win32utils projects > >> Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem > > > > <snip> > > > >> > Well, FFI is supposed to be universal now, though I > can''t get it to > >> > build on Windows at the moment. So it would be the same code for > >> > MRI > >> > (1.8 and 1.9) and Jruby. > >> > > >> In my thought, the current ruby ffi implementation don''t > care of the > >> Windows support. As far as I know, the ffi developers have no > >> definite plan about releasing of Windows binary. If it > were built to > >> binary with mingw compiler, It cannot work with Windows > API. It uses > >> dlopen,dlsym and dlclose instead of LoadLibrary,GetProcAddress and > >> FreeLibrary. > > > > That''s unfortunate. > > > >> I managed to build MSVC version of ruby ffi-0.2.0 using > win32 libffi > >> source ported by the Python''s ctypes library. You can > download ctypes > >> at sourceforge [1]. > >> What''s your thought about implementing ruby-ffi windows > version? Is > >> it worthwhile or meaningless? > > > > It''s only worthwhile if the other implementations can run it. > > Otherwise, I don''t see a practical advantage over win32-api. Do you? > > > I don''t care of it. I just want to implement win32 version of libffi. > > > Also, do you mean that your version requires Python''s > ctypes library? > > Or do you mean you''ve ported it to Ruby? > > > I have pasted the ctypes libffi win32 folder to ruby-ffi just > as Lua did on alien library. > At last, I succeeded callback function testing. > The patched source code and binary gem is at > http://121.78.227.9/ffi-0.2.0/Very impressive! In theory we should be able to rewrite win32-api with your FFI and it would be compatible with Jruby, Rubinius, etc. Is there a way to build and install it from source on Windows using MS VC++? Thanks, 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.
On Mon, Jan 26, 2009 at 3:09 PM, Berger, Daniel <Daniel.Berger at qwest.com> wrote:> > >> -----Original Message----- >> From: win32utils-devel-bounces at rubyforge.org >> [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of >> Heesob Park >> Sent: Friday, January 23, 2009 3:41 PM >> To: Development and ideas for win32utils projects >> Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem >> >> 2009/1/24 Berger, Daniel <Daniel.Berger at qwest.com>: >> >> -----Original Message----- >> >> From: win32utils-devel-bounces at rubyforge.org >> >> [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf >> Of Heesob >> >> Park >> >> Sent: Thursday, January 22, 2009 8:10 PM >> >> To: Development and ideas for win32utils projects >> >> Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem >> > >> > <snip> >> > >> >> > Well, FFI is supposed to be universal now, though I >> can''t get it to >> >> > build on Windows at the moment. So it would be the same code for >> >> > MRI >> >> > (1.8 and 1.9) and Jruby. >> >> > >> >> In my thought, the current ruby ffi implementation don''t >> care of the >> >> Windows support. As far as I know, the ffi developers have no >> >> definite plan about releasing of Windows binary. If it >> were built to >> >> binary with mingw compiler, It cannot work with Windows >> API. It uses >> >> dlopen,dlsym and dlclose instead of LoadLibrary,GetProcAddress and >> >> FreeLibrary. >> > >> > That''s unfortunate. >> > >> >> I managed to build MSVC version of ruby ffi-0.2.0 using >> win32 libffi >> >> source ported by the Python''s ctypes library. You can >> download ctypes >> >> at sourceforge [1]. >> >> What''s your thought about implementing ruby-ffi windows >> version? Is >> >> it worthwhile or meaningless? >> > >> > It''s only worthwhile if the other implementations can run it. >> > Otherwise, I don''t see a practical advantage over win32-api. Do you? >> > >> I don''t care of it. I just want to implement win32 version of libffi. >> >> > Also, do you mean that your version requires Python''s >> ctypes library? >> > Or do you mean you''ve ported it to Ruby? >> > >> I have pasted the ctypes libffi win32 folder to ruby-ffi just >> as Lua did on alien library. >> At last, I succeeded callback function testing. >> The patched source code and binary gem is at >> http://121.78.227.9/ffi-0.2.0/ > > Very impressive! > > In theory we should be able to rewrite win32-api with your FFI and it > would be compatible with Jruby, Rubinius, etc. > > Is there a way to build and install it from source on Windows using MS > VC++? >I think not without a fight. the libffi bundled in ruby-ffi includes makefiles that conform gnu-make format and don''t play realy nice with nmake.> Thanks, > > Dan > >-- Luis Lavena AREA 17 - Perfection in design is achieved not when there is nothing more to add, but rather when there is nothing more to take away. Antoine de Saint-Exup?ry
>> > >> I have pasted the ctypes libffi win32 folder to ruby-ffi just >> as Lua did on alien library. >> At last, I succeeded callback function testing. >> The patched source code and binary gem is at >> http://121.78.227.9/ffi-0.2.0/ > > Very impressive! > > In theory we should be able to rewrite win32-api with your FFI and it > would be compatible with Jruby, Rubinius, etc. > > Is there a way to build and install it from source on Windows using MS > VC++? >I guess you didn''t look into the source code package yet. I patched Rakefile and extconf.rb also. You can build and install it using your MSVC++. Regards, Park Heesob
> -----Original Message----- > From: win32utils-devel-bounces at rubyforge.org > [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of > Heesob Park > Sent: Monday, January 26, 2009 4:16 PM > To: Development and ideas for win32utils projects > Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem > > >> > > >> I have pasted the ctypes libffi win32 folder to ruby-ffi > just as Lua > >> did on alien library. > >> At last, I succeeded callback function testing. > >> The patched source code and binary gem is at > >> http://121.78.227.9/ffi-0.2.0/ > > > > Very impressive! > > > > In theory we should be able to rewrite win32-api with your > FFI and it > > would be compatible with Jruby, Rubinius, etc. > > > > Is there a way to build and install it from source on > Windows using MS > > VC++? > > > I guess you didn''t look into the source code package yet. > I patched Rakefile and extconf.rb also. > You can build and install it using your MSVC++.Cool. Where did you post the new code? The link above looks like it''s still the old code. Thanks, Dan
2009/1/28 Berger, Daniel <Daniel.Berger at qwest.com>:> > >> -----Original Message----- >> From: win32utils-devel-bounces at rubyforge.org >> [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of >> Heesob Park >> Sent: Monday, January 26, 2009 4:16 PM >> To: Development and ideas for win32utils projects >> Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem >> >> >> > >> >> I have pasted the ctypes libffi win32 folder to ruby-ffi >> just as Lua >> >> did on alien library. >> >> At last, I succeeded callback function testing. >> >> The patched source code and binary gem is at >> >> http://121.78.227.9/ffi-0.2.0/ >> > >> > Very impressive! >> > >> > In theory we should be able to rewrite win32-api with your >> FFI and it >> > would be compatible with Jruby, Rubinius, etc. >> > >> > Is there a way to build and install it from source on >> Windows using MS >> > VC++? >> > >> I guess you didn''t look into the source code package yet. >> I patched Rakefile and extconf.rb also. >> You can build and install it using your MSVC++. > > Cool. Where did you post the new code? The link above looks like it''s still the old code. >What do you expect? The current link http://121.78.227.9/ffi-0.2.0/ffi-0.2.0.tgz (948131 bytes) is the latest patched version. What''s the problem? Did you try ruby extconf.rb and nmake in the ext folder? Regards, Park Heesob
> -----Original Message----- > From: win32utils-devel-bounces at rubyforge.org > [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf Of > Heesob Park > Sent: Tuesday, January 27, 2009 5:58 PM > To: Development and ideas for win32utils projects > Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem > > 2009/1/28 Berger, Daniel <Daniel.Berger at qwest.com>: > > > > > >> -----Original Message----- > >> From: win32utils-devel-bounces at rubyforge.org > >> [mailto:win32utils-devel-bounces at rubyforge.org] On Behalf > Of Heesob > >> Park > >> Sent: Monday, January 26, 2009 4:16 PM > >> To: Development and ideas for win32utils projects > >> Subject: Re: [Win32utils-devel] win32-daemon 0.6.1 problem > >> > >> >> > > >> >> I have pasted the ctypes libffi win32 folder to ruby-ffi > >> just as Lua > >> >> did on alien library. > >> >> At last, I succeeded callback function testing. > >> >> The patched source code and binary gem is at > >> >> http://121.78.227.9/ffi-0.2.0/ > >> > > >> > Very impressive! > >> > > >> > In theory we should be able to rewrite win32-api with your > >> FFI and it > >> > would be compatible with Jruby, Rubinius, etc. > >> > > >> > Is there a way to build and install it from source on > >> Windows using MS > >> > VC++? > >> > > >> I guess you didn''t look into the source code package yet. > >> I patched Rakefile and extconf.rb also. > >> You can build and install it using your MSVC++. > > > > Cool. Where did you post the new code? The link above looks > like it''s still the old code. > > > What do you expect? The current link > http://121.78.227.9/ffi-0.2.0/ffi-0.2.0.tgz (948131 bytes) is > the latest patched version. > What''s the problem? Did you try ruby extconf.rb and nmake in > the ext folder?Oh, my fault. I tried to do "rake install" and that failed. When I did "ruby extconf.rb" + "nmake" it worked fine. Thanks! Dan