@@ -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,11 +69,7 @@ func (e *execProcess) ID() string {
6969}
7070
7171func (e * execProcess ) Pid () int {
72- return e .execState .Pid ()
73- }
74-
75- func (e * execProcess ) pidv () int {
76- return e .pid
72+ return e .pid .get ()
7773}
7874
7975func (e * execProcess ) ExitStatus () int {
@@ -145,7 +141,7 @@ func (e *execProcess) Kill(ctx context.Context, sig uint32, _ bool) error {
145141}
146142
147143func (e * execProcess ) kill (ctx context.Context , sig uint32 , _ bool ) error {
148- pid := e .pid
144+ pid := e .pid . get ()
149145 if pid != 0 {
150146 if err := unix .Kill (pid , syscall .Signal (sig )); err != nil {
151147 return errors .Wrapf (checkKillError (err ), "exec kill error" )
@@ -170,6 +166,12 @@ func (e *execProcess) Start(ctx context.Context) error {
170166}
171167
172168func (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 ()
173175 var (
174176 socket * runc.Socket
175177 pidfile = filepath .Join (e .path , fmt .Sprintf ("%s.pid" , e .id ))
@@ -229,7 +231,7 @@ func (e *execProcess) start(ctx context.Context) (err error) {
229231 if err != nil {
230232 return errors .Wrap (err , "failed to retrieve OCI runtime exec pid" )
231233 }
232- e .pid = pid
234+ e .pid . pid = pid
233235 return nil
234236}
235237
@@ -247,11 +249,11 @@ func (e *execProcess) Status(ctx context.Context) (string, error) {
247249 e .mu .Lock ()
248250 defer e .mu .Unlock ()
249251 // if we don't have a pid then the exec process has just been created
250- if e .pid == 0 {
252+ if e .pid . get () == 0 {
251253 return "created" , nil
252254 }
253255 // if we have a pid and it can be signaled, the process is running
254- if err := unix .Kill (e .pid , 0 ); err == nil {
256+ if err := unix .Kill (e .pid . get () , 0 ); err == nil {
255257 return "running" , nil
256258 }
257259 // else if we have a pid but it can nolonger be signaled, it has stopped
0 commit comments