@@ -49,7 +49,7 @@ type execProcess struct {
4949 io runc.IO
5050 status int
5151 exited time.Time
52- pid int
52+ pid * safePid
5353 closers []io.Closer
5454 stdin io.Closer
5555 stdio proc.Stdio
@@ -69,9 +69,7 @@ func (e *execProcess) ID() string {
6969}
7070
7171func (e * execProcess ) Pid () int {
72- e .mu .Lock ()
73- defer e .mu .Unlock ()
74- return e .pid
72+ return e .pid .get ()
7573}
7674
7775func (e * execProcess ) ExitStatus () int {
@@ -143,7 +141,7 @@ func (e *execProcess) Kill(ctx context.Context, sig uint32, _ bool) error {
143141}
144142
145143func (e * execProcess ) kill (ctx context.Context , sig uint32 , _ bool ) error {
146- pid := e .pid
144+ pid := e .pid . get ()
147145 if pid != 0 {
148146 if err := unix .Kill (pid , syscall .Signal (sig )); err != nil {
149147 return errors .Wrapf (checkKillError (err ), "exec kill error" )
@@ -168,6 +166,12 @@ func (e *execProcess) Start(ctx context.Context) error {
168166}
169167
170168func (e * execProcess ) start (ctx context.Context ) (err error ) {
169+ // The reaper may receive exit signal right after
170+ // the container is started, before the e.pid is updated.
171+ // In that case, we want to block the signal handler to
172+ // access e.pid until it is updated.
173+ e .pid .Lock ()
174+ defer e .pid .Unlock ()
171175 var (
172176 socket * runc.Socket
173177 pidfile = filepath .Join (e .path , fmt .Sprintf ("%s.pid" , e .id ))
@@ -227,7 +231,7 @@ func (e *execProcess) start(ctx context.Context) (err error) {
227231 if err != nil {
228232 return errors .Wrap (err , "failed to retrieve OCI runtime exec pid" )
229233 }
230- e .pid = pid
234+ e .pid . pid = pid
231235 return nil
232236}
233237
@@ -245,11 +249,11 @@ func (e *execProcess) Status(ctx context.Context) (string, error) {
245249 e .mu .Lock ()
246250 defer e .mu .Unlock ()
247251 // if we don't have a pid then the exec process has just been created
248- if e .pid == 0 {
252+ if e .pid . get () == 0 {
249253 return "created" , nil
250254 }
251255 // if we have a pid and it can be signaled, the process is running
252- if err := unix .Kill (e .pid , 0 ); err == nil {
256+ if err := unix .Kill (e .pid . get () , 0 ); err == nil {
253257 return "running" , nil
254258 }
255259 // else if we have a pid but it can nolonger be signaled, it has stopped
0 commit comments