Fixed.
[riece] / lisp / rubyserv.rb
index 97247c2..cc29694 100644 (file)
@@ -1,19 +1,22 @@
 # A simple IPC server executing Ruby programs.
 
 require 'thread'
-require 'stringio'
 
 class RubyServ
+  module C
+  end
+
   def initialize
-    @buf = StringIO.new
+    @buf = ''
     @que = Queue.new
     @thr = Hash.new
+    @cnt = 0
   end
 
   def dispatch(line)
     case line.chomp
     when /\AD /
-      @buf << unescape($')
+      @buf << $'
     when /\A(\S+)\s*/
       c = $1
       r = $'
@@ -57,23 +60,25 @@ class RubyServ
   end
 
   def dispatch_eval(c, r)
-    name, code = r.split(/\s+/, 2)
-    if @thr.include?(name) && @thr[name].alive?
-      puts("ERR 105 Parameter error: \"#{name}\" is already in use\r\n")
-      return
+    r = deq_data if r.empty?
+    name = nil
+    Thread.exclusive do
+      while @thr.include?(name = @cnt.to_s)
+       @cnt += 1
+      end
+      @thr[name] = Thread.current
     end
-    code = deq_data unless code
+    puts("S name #{name}\r\n")
     puts("OK\r\n")
-    @thr[name] = Thread.current
     Thread.current[:rubyserv_name] = name
     begin
       Thread.current[:rubyserv_error] = false
-      Thread.current[:rubyserv_response] = eval(code)
+      Thread.current[:rubyserv_response] = eval(r, C.module_eval('binding()'))
     rescue Exception => e
       Thread.current[:rubyserv_error] = true
       Thread.current[:rubyserv_response] = e
     end
-    puts("# exited #{name}\r\n")
+    puts("# exit #{name}\r\n")
   end
 
   def dispatch_poll(c, r)
@@ -81,14 +86,13 @@ class RubyServ
     if !thr
       puts("ERR 105 Parameter error: no such name \"#{r}\"\r\n")
     elsif thr.alive?
-      puts("S running\r\n")
+      puts("S running #{r}\r\n")
       puts("OK\r\n")
     else
-      @thr.delete(r)
       if thr[:rubyserv_error]
-        puts("S exited\r\n")
+        puts("S exited #{r}\r\n")
       else
-        puts("S finished\r\n")
+        puts("S finished #{r}\r\n")
       end
       if d = thr[:rubyserv_response]
         send_data(d.to_s)
@@ -97,6 +101,17 @@ class RubyServ
     end
   end
 
+  def dispatch_exit(c, r)
+    thr = @thr[r]
+    if !thr
+      puts("ERR 105 Parameter error: no such name \"#{r}\"\r\n")
+      return
+    end
+    thr.kill if thr.alive?
+    @thr.delete(r)
+    puts("OK\r\n")
+  end
+
   def escape(s)
     s.gsub(/[%\r\n]/) {|m| '%%%02X' % m[0]}
   end
@@ -119,7 +134,9 @@ class RubyServ
   end
 
   def enq_data
-    @que.enq(@buf.string)
+    d = unescape(@buf)
+    @buf = ''
+    @que.enq(d)
   end
 
   def deq_data