mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-22 17:55:11 +00:00
14d2a6d8ff
Let's hope this doesn't causes build failures for e.g. musl: I just know it's good on macOS and our Linux CI. It's been a long time. One fix this brings, is I discovered we #include assert.h or cassert in a lot of places. If those ever happen to be in a file that doesn't include common.h, or we are before common.h gets included, we're unawaringly working with the system 'assert' macro again, which may get disabled for debug builds or at least has different behavior on crash. We undef 'assert' and redefine it in common.h. Those were all eliminated, except in one catch-22 spot for maybe.h: it can't include common.h. A fix might be to make a fish_assert.h that *usually* common.h exports.
89 lines
3.1 KiB
C++
89 lines
3.1 KiB
C++
// Support for handling pids that are no longer fish jobs.
|
|
// This includes pids that have been disowned ("forgotten") and background jobs which have finished,
|
|
// but may be wait'ed.
|
|
#ifndef FISH_WAIT_HANDLE_H
|
|
#define FISH_WAIT_HANDLE_H
|
|
|
|
#include "config.h" // IWYU pragma: keep
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <list>
|
|
#include <memory>
|
|
#include <unordered_map>
|
|
#include <utility>
|
|
|
|
#include "common.h"
|
|
|
|
/// The bits of a job necessary to support 'wait' and '--on-process-exit'.
|
|
/// This may outlive the job.
|
|
struct wait_handle_t {
|
|
/// Construct from a pid, job id, and base name.
|
|
wait_handle_t(pid_t pid, internal_job_id_t jid, wcstring name)
|
|
: pid(pid), internal_job_id(jid), base_name(std::move(name)) {}
|
|
|
|
/// The pid of this process.
|
|
const pid_t pid{};
|
|
|
|
/// The internal job id of the job which contained this process.
|
|
const internal_job_id_t internal_job_id{};
|
|
|
|
/// The "base name" of this process.
|
|
/// For example if the process is "/bin/sleep" then this will be 'sleep'.
|
|
const wcstring base_name{};
|
|
|
|
/// The value appropriate for populating $status, if completed.
|
|
int status{0};
|
|
|
|
/// Set to true when the process is completed.
|
|
bool completed{false};
|
|
};
|
|
using wait_handle_ref_t = std::shared_ptr<wait_handle_t>;
|
|
|
|
/// Support for storing a list of wait handles, with a max limit set at initialization.
|
|
/// Note this class is not safe for concurrent access.
|
|
class wait_handle_store_t : noncopyable_t {
|
|
public:
|
|
// Our wait handles are arranged in a linked list for its iterator invalidation semantics: we
|
|
// may remove one without needing to update the map from pid -> handle.
|
|
using wait_handle_list_t = std::list<wait_handle_ref_t>;
|
|
|
|
/// Construct with a max limit on the number of handles we will remember.
|
|
/// The default is 1024, which is zsh's default.
|
|
explicit wait_handle_store_t(size_t limit = 1024);
|
|
|
|
/// Add a wait handle to the store. This may remove the oldest handle, if our limit is exceeded.
|
|
/// It may also remove any existing handle with that pid.
|
|
/// For convenience, this does nothing if wh is null.
|
|
void add(wait_handle_ref_t wh);
|
|
|
|
/// \return the wait handle for a pid, or nullptr if there is none.
|
|
/// This is a fast lookup.
|
|
wait_handle_ref_t get_by_pid(pid_t pid) const;
|
|
|
|
/// Remove a given wait handle, if present in this store.
|
|
void remove(const wait_handle_ref_t &wh);
|
|
|
|
/// Remove the wait handle for a pid, if present in this store.
|
|
void remove_by_pid(pid_t pid);
|
|
|
|
/// Get the list of all wait handles.
|
|
const wait_handle_list_t &get_list() const { return handles_; }
|
|
|
|
/// Convenience to return the size, for testing.
|
|
size_t size() const { return handles_.size(); }
|
|
|
|
private:
|
|
using list_node_t = typename wait_handle_list_t::iterator;
|
|
|
|
/// The list of all wait handles. New ones come on the front, the last one is oldest.
|
|
wait_handle_list_t handles_{};
|
|
|
|
/// Map from pid to the wait handle's position in the list.
|
|
std::unordered_map<pid_t, list_node_t> handle_map_{};
|
|
|
|
/// Max supported wait handles.
|
|
const size_t limit_;
|
|
};
|
|
|
|
#endif
|