INIT_LIST_HEAD(old);
}
+/*
+ * This is exactly the same as a normal list_head, except that it can be
+ * declared volatile (e.g., if you have a list that may be accessed from signal
+ * handlers).
+ */
+struct volatile_list_head {
+ volatile struct volatile_list_head *next, *prev;
+};
+
+#define VOLATILE_LIST_HEAD(name) \
+ volatile struct volatile_list_head name = { &(name), &(name) }
+
+static inline void __volatile_list_del(volatile struct volatile_list_head *prev,
+ volatile struct volatile_list_head *next)
+{
+ next->prev = prev;
+ prev->next = next;
+}
+
+static inline void volatile_list_del(volatile struct volatile_list_head *elem)
+{
+ __volatile_list_del(elem->prev, elem->next);
+}
+
+static inline int volatile_list_empty(volatile struct volatile_list_head *head)
+{
+ return head == head->next;
+}
+
+static inline void volatile_list_add(volatile struct volatile_list_head *newp,
+ volatile struct volatile_list_head *head)
+{
+ head->next->prev = newp;
+ newp->next = head->next;
+ newp->prev = head;
+ head->next = newp;
+}
+
#endif /* LIST_H */
#include "tempfile.h"
#include "sigchain.h"
-static struct tempfile *volatile tempfile_list;
+static VOLATILE_LIST_HEAD(tempfile_list);
static void remove_tempfiles(int in_signal_handler)
{
pid_t me = getpid();
- struct tempfile *volatile p;
+ volatile struct volatile_list_head *pos;
+
+ list_for_each(pos, &tempfile_list) {
+ struct tempfile *p = list_entry(pos, struct tempfile, list);
- for (p = tempfile_list; p; p = p->next) {
if (!is_tempfile_active(p) || p->owner != me)
continue;
*/
static void prepare_tempfile_object(struct tempfile *tempfile)
{
- if (!tempfile_list) {
+ if (volatile_list_empty(&tempfile_list)) {
/* One-time initialization */
sigchain_push_common(remove_tempfiles_on_signal);
atexit(remove_tempfiles_on_exit);
tempfile->active = 0;
tempfile->owner = 0;
strbuf_init(&tempfile->filename, 0);
- tempfile->next = tempfile_list;
- tempfile_list = tempfile;
+ volatile_list_add(&tempfile->list, &tempfile_list);
tempfile->on_list = 1;
} else if (tempfile->filename.len) {
/* This shouldn't happen, but better safe than sorry. */
#ifndef TEMPFILE_H
#define TEMPFILE_H
+#include "list.h"
+
/*
* Handle temporary files.
*
*/
struct tempfile {
- struct tempfile *volatile next;
+ volatile struct volatile_list_head list;
volatile sig_atomic_t active;
volatile int fd;
FILE *volatile fp;