<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -1,4 +1,5 @@
 == 1.0.0 The Big release
+ * Add --force (-f) option to force stopping of a daemonized server, fixes [#72 state:resolved]
  * Update halycon adapter loader [mtodd]
 
 == 0.8.2 Double Margarita release</diff>
      <filename>CHANGELOG</filename>
    </modified>
    <modified>
      <diff>@@ -83,7 +83,7 @@ module Thin
         raise OptionRequired, :pid unless @options[:pid]
       
         tail_log(@options[:log]) do
-          if Server.kill(@options[:pid], @options[:timeout] || 60)
+          if Server.kill(@options[:pid], @options[:force] ? 0 : (@options[:timeout] || 60))
             wait_for_file :deletion, @options[:pid]
           end
         end</diff>
      <filename>lib/thin/controllers/controller.rb</filename>
    </modified>
    <modified>
      <diff>@@ -89,22 +89,16 @@ module Thin
     end
     
     module ClassMethods
-      # Send a QUIT signal the process which PID is stored in +pid_file+.
+      # Send a QUIT or INT (if timeout is +0+) signal the process which
+      # PID is stored in +pid_file+.
       # If the process is still running after +timeout+, KILL signal is
       # sent.
       def kill(pid_file, timeout=60)
-        if pid = send_signal('QUIT', pid_file)
-          Timeout.timeout(timeout) do
-            sleep 0.1 while Process.running?(pid)
-          end
+        if timeout == 0
+          send_signal('INT', pid_file, timeout)
+        else
+          send_signal('QUIT', pid_file, timeout)
         end
-      rescue Timeout::Error
-        print &quot;Timeout! &quot;
-        send_signal('KILL', pid_file)
-      rescue Interrupt
-        send_signal('KILL', pid_file)
-      ensure
-        File.delete(pid_file) if File.exist?(pid_file)
       end
       
       # Restart the server by sending HUP signal.
@@ -113,21 +107,28 @@ module Thin
       end
       
       # Send a +signal+ to the process which PID is stored in +pid_file+.
-      def send_signal(signal, pid_file)
-        if File.exist?(pid_file) &amp;&amp; pid = open(pid_file).read
+      def send_signal(signal, pid_file, timeout=60)
+        if File.file?(pid_file) &amp;&amp; pid = open(pid_file).read
           pid = pid.to_i
           print &quot;Sending #{signal} signal to process #{pid} ... &quot;
           Process.kill(signal, pid)
+          Timeout.timeout(timeout) do
+            sleep 0.1 while Process.running?(pid)
+          end
           puts
-          pid
         else
           puts &quot;Can't stop process, no PID found in #{pid_file}&quot;
-          nil
         end
+      rescue Timeout::Error
+        puts &quot;Timeout! &quot;
+        Process.kill(&quot;KILL&quot;, pid)
+      rescue Interrupt
+        Process.kill(&quot;KILL&quot;, pid)
       rescue Errno::ESRCH # No such process
         puts &quot;process not found!&quot;
-        nil
-      end
+      ensure
+        File.delete(pid_file) if File.exist?(pid_file)
+      end      
     end
     
     protected</diff>
      <filename>lib/thin/daemonizing.rb</filename>
    </modified>
    <modified>
      <diff>@@ -102,6 +102,7 @@ module Thin
         opts.on(&quot;-b&quot;, &quot;--backend CLASS&quot;, &quot;Backend to use, full classname&quot;)              { |name| @options[:backend] = name }
         opts.on(&quot;-t&quot;, &quot;--timeout SEC&quot;, &quot;Request or command timeout in sec &quot; +            
                                        &quot;(default: #{@options[:timeout]})&quot;)              { |sec| @options[:timeout] = sec.to_i }
+        opts.on(&quot;-f&quot;, &quot;--force&quot;, &quot;Force the execution of the command&quot;)                  { @options[:force] = true }
         opts.on(      &quot;--max-conns NUM&quot;, &quot;Maximum number of connections &quot; +
                                          &quot;(default: #{@options[:max_conns]})&quot;,
                                          &quot;Might require sudo to set higher then 1024&quot;)  { |num| @options[:max_conns] = num.to_i } unless Thin.win?</diff>
      <filename>lib/thin/runner.rb</filename>
    </modified>
    <modified>
      <diff>@@ -94,6 +94,23 @@ describe 'Daemonizing' do
     File.exist?(@server.pid_file).should be_false
   end
   
+  it 'should force kill process in pid file' do
+    @pid = fork do
+      @server.daemonize
+      loop { sleep 3 }
+    end
+  
+    server_should_start_in_less_then 3
+    
+    @pid = @server.pid
+  
+    silence_stream STDOUT do
+      TestServer.kill(@server.pid_file, 0)
+    end
+  
+    File.exist?(@server.pid_file).should be_false
+  end
+  
   it 'should send kill signal if timeout' do
     @pid = fork do
       @server.should_receive(:stop) # pretend we cannot handle the INT signal</diff>
      <filename>spec/daemonizing_spec.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>fef2e74f143dee8fea49e110e51aa3a66ecccc9b</id>
    </parent>
  </parents>
  <author>
    <name>macournoyer</name>
    <email>macournoyer@gmail.com</email>
  </author>
  <url>http://github.com/macournoyer/thin/commit/729b76ae2391a197e14d1bb8ec2d40f82a47b1a4</url>
  <id>729b76ae2391a197e14d1bb8ec2d40f82a47b1a4</id>
  <committed-date>2008-07-13T20:27:39-07:00</committed-date>
  <authored-date>2008-07-13T20:27:39-07:00</authored-date>
  <message>Add --force (-f) option to force stopping of a daemonized server, [#72 state:resolved]</message>
  <tree>f79aa8ce3ad7c533e12aea53033d85a8bf4e36f4</tree>
  <committer>
    <name>macournoyer</name>
    <email>macournoyer@gmail.com</email>
  </committer>
</commit>
