#265: Failure when fetching a file with wget
-------------------------+--------------------------------------------------
  Reporter:  toots       |       Owner:  admin      
      Type:  Bugs        |      Status:  new        
  Priority:  8           |   Milestone:  NEAR FUTURE
 Component:  Liquidsoap  |     Version:  0.9.0+svn  
Resolution:              |    Keywords:             
       Mac:  1           |       Linux:  1          
    Netbsd:  1           |       Other:  1          
   Freebsd:  1           |  
-------------------------+--------------------------------------------------

Comment(by toots):

 Ok, it kept on crashing here, so I took some time to try to fix this.

 Unfortunately, I don't understand anything on the initial code:
 {{{
   (* We create a fresh stdin for the process,
    * and another one, unused by the child, on which we'll wait for EOF
    * as a mean to detect termination. *)
   let (iR,iW) = Unix.pipe () in
   let (xR,xW) = Unix.pipe () in
   let pid =
     Unix.create_process
       program (command program s local)
       iR Unix.stderr Unix.stderr
   in
   dlog#f 4 "Executing %s %S %S" program s local ;
   let timeout = max 0. (maxtime -. Unix.gettimeofday ()) in
     Unix.close iR ;
     Unix.close xW ;
     if Unix.select [xR] [] [] timeout = ([],[],[]) then
       Unix.kill pid 9 ;
     let (p,code) = Unix.waitpid [] pid in
       assert (p <> 0) ;
       dlog#f 4 "Download process finished (%s)"
         (match code with
         | Unix.WSIGNALED _ -> "killed"
         | Unix.WEXITED 0 -> "ok"
         | _ -> "error") ;
       Unix.close iW ;
       Unix.close xR ;
 }}}

 In particular, I don't understand why the {{{Unix.select}}} will wake up
 when the process has finished..

 I have rewritten this using the same technique as I used for the external
 encoders:
 {{{
     let proc =
       try
         Unix.open_process_in (command program s local)
       with
         | _ -> assert false
     in
     let xR = Unix.descr_of_in_channel proc in
     dlog#f 4 "Executing %s %S %S" program s local ;
     let rec wait_timeout () =
       let timeout = max 0. (maxtime -. Unix.gettimeofday ()) in
       let (x,_,_) = Unix.select [xR] [] [] timeout in
       if List.mem xR x then
        begin
         if input proc tmpbuf 0 1024 > 0 then
           wait_timeout ()
         else
          begin
           dlog#f 4 "Process %s %S %S exited." program s local ;
           Unix.close_process_in proc
          end
        end
       else
        begin
         dlog#f 4 "Timeout expired: killing process %s %S %S" program s
 local ;
         Unix.close_process_in proc
        end
     in
     begin
      try
        let code = wait_timeout () in
          dlog#f 4 "Download process finished (%s)"
            (match code with
               | Unix.WSIGNALED _ -> "killed"
               | Unix.WEXITED 0 -> "ok"
               | _ -> "error") ;
 }}}

 Such an implementation seems much more correct to me. What do you think ?

 It is in production on radiopi, so I should catch any error in this piece
 of code..

 Corresponding patch attached.

-- 
Ticket URL: <http://savonet.rastageeks.org/ticket/265#comment:1>
Savonet <http://savonet.rastageeks.org/>
Let's program our stream !
------------------------------------------------------------------------------
Stay on top of everything new and different, both inside and 
around Java (TM) technology - register by April 22, and save
$200 on the JavaOne (SM) conference, June 2-5, 2009, San Francisco.
300 plus technical and hands-on sessions. Register today. 
Use priority code J9JMT32. http://p.sf.net/sfu/p
_______________________________________________
Savonet-trac mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/savonet-trac

Reply via email to