diff options
Diffstat (limited to 'hurd/hurd')
-rw-r--r-- | hurd/hurd/lookup.h | 31 | ||||
-rw-r--r-- | hurd/hurd/signal.h | 38 |
2 files changed, 46 insertions, 23 deletions
diff --git a/hurd/hurd/lookup.h b/hurd/hurd/lookup.h index 6911b8f5b9..565ab317c8 100644 --- a/hurd/hurd/lookup.h +++ b/hurd/hurd/lookup.h @@ -1,5 +1,5 @@ /* Declarations of file name translation functions for the GNU Hurd. -Copyright (C) 1995 Free Software Foundation, Inc. +Copyright (C) 1995, 1996 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -98,4 +98,33 @@ error_t hurd_file_name_lookup_retry (error_t (*use_init_port) file_t *result); +/* If FILE_NAME contains a '/', or PATH is NULL, call FUN with FILE_NAME, and + return the result (if PREFIXED_NAME is non-NULL, setting *PREFIXED_NAME to + NULL). Otherwise, call FUN repeatedly with FILE_NAME prefixed with each + successive `:' separated element of PATH, returning whenever FUN returns + 0 (if PREFIXED_NAME is non-NULL, setting *PREFIXED_NAME to the resulting + prefixed path). If FUN never returns 0, return the first non-ENOENT + return value, or ENOENT if there is none. */ +error_t file_name_path_scan (const char *file_name, const char *path, + error_t (*fun)(const char *name), + char **prefixed_name); + +/* Lookup FILE_NAME and return the node opened with FLAGS & MODE in result + (see hurd_file_name_lookup for details), but a simple filename (without + any directory prefixes) will be consectutively prefixed with the pathnames + in the `:' separated list PATH until one succeeds in a successful lookup. + If none succeed, then the first error that wasn't ENOENT is returned, or + ENOENT if no other errors were returned. If PREFIXED_NAME is non-NULL, + then if RESULT is looked up directly, *PREFIXED_NAME is set to NULL, and + if it is looked up using a prefix from PATH, *PREFIXED_NAME is set to + malloced storage containing the prefixed name. */ +error_t hurd_file_name_path_lookup (error_t (*use_init_port) + (int which, + error_t (*operate) (mach_port_t)), + file_t (*get_dtable_port) (int fd), + const char *file_name, const char *path, + int flags, mode_t mode, + file_t *result, char **prefixed_name); + + #endif /* hurd/lookup.h */ diff --git a/hurd/hurd/signal.h b/hurd/hurd/signal.h index 1973bcdb3c..fdaafdf459 100644 --- a/hurd/hurd/signal.h +++ b/hurd/hurd/signal.h @@ -47,9 +47,9 @@ struct hurd_signal_preempter; /* <hurd/sigpreempt.h> */ struct hurd_sigstate { - spin_lock_t lock; /* Locks most of the rest of the structure. */ + spin_lock_t critical_section_lock; /* Held if in critical section. */ - int critical_section; /* Nonzero if in critical section. */ + spin_lock_t lock; /* Locks most of the rest of the structure. */ thread_t thread; struct hurd_sigstate *next; /* Linked-list of thread sigstates. */ @@ -159,27 +159,22 @@ _hurd_critical_section_lock (void) (void *) __hurd_threadvar_location (_HURD_THREADVAR_SIGSTATE); struct hurd_sigstate *ss = *location; if (ss == NULL) - /* The thread variable is unset; this must be the first time we've - asked for it. In this case, the critical section flag cannot - possible already be set. Look up our sigstate structure the slow - way; this locks the sigstate lock. */ - ss = *location = _hurd_thread_sigstate (__mach_thread_self ()); - else - __spin_lock (&ss->lock); - - if (ss->critical_section) { - /* We are already in a critical section, so do nothing. */ + /* The thread variable is unset; this must be the first time we've + asked for it. In this case, the critical section flag cannot + possible already be set. Look up our sigstate structure the slow + way; this locks the sigstate lock. */ + ss = *location = _hurd_thread_sigstate (__mach_thread_self ()); __spin_unlock (&ss->lock); - return NULL; } - /* Set the critical section flag so no signal handler will run. */ - ss->critical_section = 1; - __spin_unlock (&ss->lock); + if (! __spin_try_lock (&ss->critical_section_lock)) + /* We are already in a critical section, so do nothing. */ + return NULL; - /* Return our sigstate pointer; this will be passed to - _hurd_critical_section_unlock to clear the critical section flag. */ + /* With the critical section lock held no signal handler will run. + Return our sigstate pointer; this will be passed to + _hurd_critical_section_unlock to unlock it. */ return ss; } @@ -191,19 +186,18 @@ _hurd_critical_section_unlock (void *our_lock) return; else { - /* It was us who acquired the critical section lock. Clear the - critical section flag. */ + /* It was us who acquired the critical section lock. Unlock it. */ struct hurd_sigstate *ss = our_lock; sigset_t pending; __spin_lock (&ss->lock); - ss->critical_section = 0; + __spin_unlock (&ss->critical_section_lock); pending = ss->pending & ~ss->blocked; __spin_unlock (&ss->lock); if (pending) /* There are unblocked signals pending, which weren't delivered because we were in the critical section. Tell the signal thread to deliver them now. */ - __msg_sig_post (_hurd_msgport, 0, __mach_task_self ()); + __msg_sig_post (_hurd_msgport, 0, 0, __mach_task_self ()); } } |