summaryrefslogtreecommitdiff
path: root/libdiskfs/sync-interval.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1995-10-05 04:45:56 +0000
committerRoland McGrath <roland@gnu.org>1995-10-05 04:45:56 +0000
commitba5a04007fb8ac0ca0618853c6e53557abeda75d (patch)
tree3cd9ccc2176ced9595b470b2f1f17b1fd4199afb /libdiskfs/sync-interval.c
parentefe777f6f6a31ed5369a9693be434cb3753d34de (diff)
(periodic_sync_lock): Variable removed.
(diskfs_set_sync_interval): Use ports_inhibit_port_rpcs on `pi' instead of the spin lock. (periodic_sync): Don't use the lock. Put ports_begin_rpc before check of periodic_sync_thread.
Diffstat (limited to 'libdiskfs/sync-interval.c')
-rw-r--r--libdiskfs/sync-interval.c67
1 files changed, 34 insertions, 33 deletions
diff --git a/libdiskfs/sync-interval.c b/libdiskfs/sync-interval.c
index 2c1d398f..da7fba81 100644
--- a/libdiskfs/sync-interval.c
+++ b/libdiskfs/sync-interval.c
@@ -27,12 +27,12 @@
#include "priv.h"
/* The thread that's doing the syncing. */
-static cthread_t periodic_sync_thread = 0;
+static cthread_t periodic_sync_thread;
-/* A lock to lock before changing any of the above. */
-static spin_lock_t periodic_sync_lock = SPIN_LOCK_INITIALIZER;
-
-static struct port_info *pi = 0;
+/* This port represents the periodic sync service as if it were
+ an RPC. We can use ports_inhibit_port_rpcs on this port to guarantee
+ that the periodic_sync_thread is quiescent. */
+static struct port_info *pi;
@@ -48,31 +48,30 @@ diskfs_set_sync_interval (int interval)
{
error_t err = 0;
- spin_lock (&periodic_sync_lock);
-
if (!pi)
pi = ports_allocate_port (diskfs_port_bucket,
sizeof (struct port_info),
diskfs_control_class);
- if (!err)
- /* Here we just set the new thread; any existing thread will notice when it
- wakes up and go away silently. */
- if (interval == 0)
- periodic_sync_thread = 0;
- else
- {
- periodic_sync_thread =
- cthread_fork ((cthread_fn_t)periodic_sync, (any_t)interval);
- if (periodic_sync_thread)
- cthread_detach (periodic_sync_thread);
- else
- err = ED;
- }
-
- spin_unlock (&periodic_sync_lock);
-
- return 0;
+ ports_inhibit_port_rpcs (pi);
+
+ /* Here we just set the new thread; any existing thread will notice when it
+ wakes up and go away silently. */
+ if (interval == 0)
+ periodic_sync_thread = 0;
+ else
+ {
+ periodic_sync_thread =
+ cthread_fork ((cthread_fn_t)periodic_sync, (any_t)interval);
+ if (periodic_sync_thread)
+ cthread_detach (periodic_sync_thread);
+ else
+ err = EIEIO;
+ }
+
+ ports_resume_port_rpcs (pi);
+
+ return err;
}
/* ---------------------------------------------------------------- */
@@ -85,20 +84,22 @@ periodic_sync (int interval)
{
for (;;)
{
- cthread_t thread;
struct rpc_info link;
- spin_lock (&periodic_sync_lock);
- thread = periodic_sync_thread;
- spin_unlock (&periodic_sync_lock);
+ /* This acts as a lock against creation of a new sync thread
+ while we are in the process of syncing. */
+ ports_begin_rpc (pi, &link);
- if (thread != cthread_self ())
- /* We've been superseded as the sync thread... Just die silently. */
- return;
+ if (periodic_sync_thread != cthread_self ())
+ {
+ /* We've been superseded as the sync thread. Just die silently. */
+ ports_end_rpc (pi, &link);
+ return;
+ }
- ports_begin_rpc (pi, &link);
diskfs_sync_everything (0);
diskfs_set_hypermetadata (0, 0);
+
ports_end_rpc (pi, &link);
/* Wait until next time. */