2
2
require 'singleton'
3
3
require 'timeout'
4
4
5
+ DESIRED_DISPLAY = ":1.0" . freeze
6
+
5
7
module ArduinoCI
6
8
7
9
# When arduino commands run, they need a graphical display.
@@ -24,6 +26,42 @@ def existing_display?
24
26
false
25
27
end
26
28
29
+ # check whether a process is alive
30
+ # https://stackoverflow.com/a/32513298/2063546
31
+ def alive? ( pid )
32
+ Process . kill ( 0 , pid )
33
+ true
34
+ rescue
35
+ false
36
+ end
37
+
38
+ # check whether an X server is taking connections
39
+ def xserver_exist? ( display )
40
+ system ( { "DISPLAY" => display } , "xdpyinfo" , out : File ::NULL , err : File ::NULL )
41
+ end
42
+
43
+ # wait for the xvfb command to launch
44
+ # @param display [String] the value of the DISPLAY env var
45
+ # @param pid [Int] the process of Xvfb
46
+ # @param timeout [Int] the timeout in seconds
47
+ # @return [Bool] whether we detected a launch
48
+ def xvfb_launched? ( display , pid , timeout )
49
+ Timeout . timeout ( timeout ) do
50
+ loop do
51
+ unless alive? pid
52
+ puts "Xvfb process has died"
53
+ return false
54
+ end
55
+ x = xserver_exist? display
56
+ puts "xdpyinfo reports X server status as #{ x } "
57
+ return true if x
58
+ sleep ( 0.1 )
59
+ end
60
+ end
61
+ rescue Timeout ::Error
62
+ false
63
+ end
64
+
27
65
# enable a virtual display
28
66
def enable
29
67
if @existing
@@ -35,14 +73,18 @@ def enable
35
73
return unless @pid . nil? # TODO: disable first?
36
74
37
75
# open Xvfb
38
- xvfb_cmd = [ "Xvfb" , ":1" , "-ac" , "-screen" , "0" , "1280x1024x16" ]
76
+ xvfb_cmd = [
77
+ "Xvfb" ,
78
+ "+extension" , "RANDR" ,
79
+ ":1" ,
80
+ "-ac" ,
81
+ "-screen" , "0" ,
82
+ "1280x1024x16" ,
83
+ ]
39
84
puts "pipeline_start for Xvfb"
40
85
pipe = IO . popen ( xvfb_cmd )
41
86
@pid = pipe . pid
42
- sleep ( 3 ) # TODO: test a connection to the X server?
43
- @enabled = true
44
- puts "\n \n xdpyinfo:\n \n "
45
- system ( environment , "xdpyinfo" )
87
+ @enabled = xvfb_launched? ( DESIRED_DISPLAY , @pid , 30 )
46
88
end
47
89
48
90
# disable the virtual display
@@ -106,7 +148,7 @@ def run_silent(*args)
106
148
def environment
107
149
return nil unless @existing || @enabled
108
150
return { } if @existing
109
- { "DISPLAY" => ":1.0" }
151
+ { "DISPLAY" => DESIRED_DISPLAY }
110
152
end
111
153
112
154
# On finalize, ensure child process is ended
0 commit comments