Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions components/lwp/lwp.c
Original file line number Diff line number Diff line change
Expand Up @@ -514,22 +514,22 @@ pid_t lwp_execve(char *filename, int debug, int argc, char **argv, char **envp)

if ((tid = lwp_tid_get()) == 0)
{
lwp_ref_dec(lwp);
lwp_pid_rollback(lwp);
return -ENOMEM;
}
#ifdef ARCH_MM_MMU
if (lwp_user_space_init(lwp, 0) != 0)
{
lwp_tid_put(tid);
lwp_ref_dec(lwp);
lwp_pid_rollback(lwp);
return -ENOMEM;
}
#endif

if ((aux = argscopy(lwp, argc, argv, envp)) == RT_NULL)
{
lwp_tid_put(tid);
lwp_ref_dec(lwp);
lwp_pid_rollback(lwp);
return -ENOMEM;
}

Expand Down Expand Up @@ -629,7 +629,7 @@ pid_t lwp_execve(char *filename, int debug, int argc, char **argv, char **envp)
}

lwp_tid_put(tid);
lwp_ref_dec(lwp);
lwp_pid_rollback(lwp);

return -RT_ERROR;
}
Expand Down
29 changes: 29 additions & 0 deletions components/lwp/lwp_pid.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,35 @@ void lwp_pid_put(struct rt_lwp *lwp)
lwp_ref_dec(lwp);
}

/**
* @brief Roll back a PID allocated for a process that never became runnable.
*
* @param[in,out] lwp The lightweight process whose PID allocation should be
* undone. The LWP must have been allocated a PID, but must
* not have been made visible as a runnable user task.
*
* @note This helper is intended for exec/spawn failure paths after PID
* allocation and before task startup. It removes the PID table entry,
* clears lwp->pid, and drops the initial LWP reference.
*
* Do not use lwp_pid_put() for this case. lwp_pid_put() has process-exit
* semantics: when the PID tree becomes empty it wakes waiters and keeps
* the PID lock held to prevent new PID allocation. A failed exec rollback
* must release the PID lock unconditionally so later LWP launches can
* still allocate PIDs, especially in init-less boot flows.
*/
void lwp_pid_rollback(struct rt_lwp *lwp)
{
_free_proc_dentry(lwp);

lwp_pid_lock_take();
lwp_pid_put_locked(lwp->pid);
lwp_pid_lock_release();

lwp->pid = 0;
lwp_ref_dec(lwp);
}

/**
* @brief Set the LWP for a given PID while holding the PID lock
*
Expand Down
1 change: 1 addition & 0 deletions components/lwp/lwp_pid.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ int lwp_pid_init(void);
int lwp_pid_wait_for_empty(int wait_flags, rt_tick_t to);
int lwp_pid_for_each(int (*cb)(pid_t pid, void *data), void *data);
void lwp_pid_put(struct rt_lwp *lwp);
void lwp_pid_rollback(struct rt_lwp *lwp);
void lwp_pid_lock_take(void);
void lwp_pid_lock_release(void);

Expand Down
Loading