guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] 17/24: Replace scm_make_mutex_with_flags


From: Andy Wingo
Subject: [Guile-commits] 17/24: Replace scm_make_mutex_with_flags
Date: Sun, 6 Nov 2016 18:00:46 +0000 (UTC)

wingo pushed a commit to branch master
in repository guile.

commit 768246124164243059b0eeb772d3bb5bf1db0db9
Author: Andy Wingo <address@hidden>
Date:   Sat Nov 5 11:14:17 2016 +0100

    Replace scm_make_mutex_with_flags
    
    * libguile/threads.c (enum fat_mutex_kind): New data type, replacing
      separate flags.
      (struct fat_mutex): Adapt.
      (make_fat_mutex): Fat mutexes can only be one of three kinds, not one
      of 4 kinds.  (Recursive unowned mutexes are not a thing.)
      (scm_make_mutex): Adapt.
      (scm_make_mutex_with_kind): New function, replacing
      scm_make_mutex_with_flags.  Still bound to make-mutex.
      (scm_make_recursive_mutex): Adapt.
      (fat_mutex_lock, fat_mutex_unlock): Adapt.
    * libguile/threads.h (scm_make_mutex_with_kind): New decl.
    * libguile/deprecated.h:
    * libguile/deprecated.c (scm_make_mutex_with_flags): Deprecate.
---
 libguile/deprecated.c |   22 +++++++++++++++
 libguile/deprecated.h |    4 +++
 libguile/threads.c    |   75 +++++++++++++++++++++++++++++--------------------
 libguile/threads.h    |    2 +-
 4 files changed, 72 insertions(+), 31 deletions(-)

diff --git a/libguile/deprecated.c b/libguile/deprecated.c
index c8d353f..fd671e9 100644
--- a/libguile/deprecated.c
+++ b/libguile/deprecated.c
@@ -680,6 +680,28 @@ scm_dynwind_critical_section (SCM mutex)
 
 
 
+SCM
+scm_make_mutex_with_flags (SCM flags)
+{
+  SCM kind = SCM_UNDEFINED;
+
+  scm_c_issue_deprecation_warning
+    ("'scm_make_mutex_with_flags' is deprecated.  "
+     "Use 'scm_make_mutex_with_kind' instead.");
+
+  if (!scm_is_null (flags))
+    {
+      if (!scm_is_null (scm_cdr (flags)))
+       scm_misc_error (NULL, "too many mutex options: ~a", scm_list_1 (flags));
+      kind = scm_car (flags);
+    }
+
+  return scm_make_mutex_with_kind (kind);
+}
+
+
+
+
 void
 scm_i_init_deprecated ()
 {
diff --git a/libguile/deprecated.h b/libguile/deprecated.h
index d8ce816..d20ff5b 100644
--- a/libguile/deprecated.h
+++ b/libguile/deprecated.h
@@ -238,6 +238,10 @@ SCM_DEPRECATED void scm_dynwind_critical_section (SCM 
mutex);
 
 
 
+SCM_DEPRECATED SCM scm_make_mutex_with_flags (SCM flags);
+
+
+
 void scm_i_init_deprecated (void);
 
 #endif
diff --git a/libguile/threads.c b/libguile/threads.c
index 9d9b01a..d44d3b1 100644
--- a/libguile/threads.c
+++ b/libguile/threads.c
@@ -510,15 +510,31 @@ guilify_self_2 (SCM parent)
    debugging.
 */
 
+enum fat_mutex_kind {
+  /* A standard mutex can only be locked once.  If you try to lock it
+     again from the thread that locked it to begin with (the "owner"
+     thread), it throws an error.  It can only be unlocked from the
+     thread that locked it in the first place.  */
+  FAT_MUTEX_STANDARD,
+  /* A recursive mutex can be locked multiple times by its owner.  It
+     then has to be unlocked the corresponding number of times, and like
+     standard mutexes can only be unlocked by the owner thread.  */
+  FAT_MUTEX_RECURSIVE,
+  /* An unowned mutex is like a standard mutex, except that it can be
+     unlocked by any thread.  A corrolary of this behavior is that a
+     thread's attempt to lock a mutex that it already owns will block
+     instead of signalling an error, as it could be that some other
+     thread unlocks the mutex, allowing the owner thread to proceed.
+     This kind of mutex is a bit strange and is here for use by
+     SRFI-18.  */
+  FAT_MUTEX_UNOWNED
+};
+
 typedef struct {
   scm_i_pthread_mutex_t lock;
   SCM owner;
   int level; /* how much the owner owns us.  <= 1 for non-recursive mutexes */
-
-  int recursive; /* allow recursive locking? */
-  int allow_external_unlock; /* is it an error to unlock a mutex that is not
-                               owned by the current thread? */
-
+  enum fat_mutex_kind kind;
   SCM waiting;    /* the threads waiting for this mutex. */
 } fat_mutex;
 
@@ -1064,7 +1080,7 @@ fat_mutex_print (SCM mx, SCM port, scm_print_state 
*pstate SCM_UNUSED)
 }
 
 static SCM
-make_fat_mutex (int recursive, int external_unlock)
+make_fat_mutex (enum fat_mutex_kind kind)
 {
   fat_mutex *m;
   SCM mx;
@@ -1076,10 +1092,7 @@ make_fat_mutex (int recursive, int external_unlock)
   memcpy (&m->lock, &lock, sizeof (m->lock));
   m->owner = SCM_BOOL_F;
   m->level = 0;
-
-  m->recursive = recursive;
-  m->allow_external_unlock = external_unlock;
-
+  m->kind = kind;
   m->waiting = SCM_EOL;
   SCM_NEWSMOB (mx, scm_tc16_mutex, (scm_t_bits) m);
   m->waiting = make_queue ();
@@ -1088,32 +1101,34 @@ make_fat_mutex (int recursive, int external_unlock)
 
 SCM scm_make_mutex (void)
 {
-  return scm_make_mutex_with_flags (SCM_EOL);
+  return scm_make_mutex_with_kind (SCM_UNDEFINED);
 }
 
 SCM_SYMBOL (allow_external_unlock_sym, "allow-external-unlock");
 SCM_SYMBOL (recursive_sym, "recursive");
 
-SCM_DEFINE (scm_make_mutex_with_flags, "make-mutex", 0, 0, 1,
-           (SCM flags),
-           "Create a new mutex. ")
-#define FUNC_NAME s_scm_make_mutex_with_flags
+SCM_DEFINE (scm_make_mutex_with_kind, "make-mutex", 0, 1, 0,
+           (SCM kind),
+           "Create a new mutex.  If @var{kind} is not given, the mutex\n"
+            "will be a standard non-recursive mutex.  Otherwise pass\n"
+            "@code{recursive} to make a recursive mutex, or\n"
+            "@code{allow-external-unlock} to make a non-recursive mutex\n"
+            "that can be unlocked from any thread.")
+#define FUNC_NAME s_scm_make_mutex_with_kind
 {
-  int external_unlock = 0, recursive = 0;
+  enum fat_mutex_kind mkind = FAT_MUTEX_STANDARD;
 
-  SCM ptr = flags;
-  while (! scm_is_null (ptr))
+  if (!SCM_UNBNDP (kind))
     {
-      SCM flag = SCM_CAR (ptr);
-      if (scm_is_eq (flag, allow_external_unlock_sym))
-       external_unlock = 1;
-      else if (scm_is_eq (flag, recursive_sym))
-       recursive = 1;
+      if (scm_is_eq (kind, allow_external_unlock_sym))
+       mkind = FAT_MUTEX_UNOWNED;
+      else if (scm_is_eq (kind, recursive_sym))
+       mkind = FAT_MUTEX_RECURSIVE;
       else
-       SCM_MISC_ERROR ("unsupported mutex option: ~a", scm_list_1 (flag));
-      ptr = SCM_CDR (ptr);
+       SCM_MISC_ERROR ("unsupported mutex kind: ~a", scm_list_1 (kind));
     }
-  return make_fat_mutex (recursive, external_unlock);
+
+  return make_fat_mutex (mkind);
 }
 #undef FUNC_NAME
 
@@ -1122,7 +1137,7 @@ SCM_DEFINE (scm_make_recursive_mutex, 
"make-recursive-mutex", 0, 0, 0,
            "Create a new recursive mutex. ")
 #define FUNC_NAME s_scm_make_recursive_mutex
 {
-  return make_fat_mutex (1, 0);
+  return scm_make_mutex_with_kind (recursive_sym);
 }
 #undef FUNC_NAME
 
@@ -1147,9 +1162,9 @@ fat_mutex_lock (SCM mutex, scm_t_timespec *timeout, int 
*ret)
          *ret = 1;
          break;
        }
-      else if (scm_is_eq (m->owner, new_owner) && !m->allow_external_unlock)
+      else if (scm_is_eq (m->owner, new_owner) && m->kind != FAT_MUTEX_UNOWNED)
        {
-         if (m->recursive)
+         if (m->kind == FAT_MUTEX_RECURSIVE)
            {
              m->level++;
              *ret = 1;
@@ -1283,7 +1298,7 @@ fat_mutex_unlock (SCM mutex, SCM cond,
           scm_i_pthread_mutex_unlock (&m->lock);
           scm_misc_error (NULL, "mutex not locked", SCM_EOL);
        }
-      else if (!m->allow_external_unlock)
+      else if (m->kind != FAT_MUTEX_UNOWNED)
        {
          scm_i_pthread_mutex_unlock (&m->lock);
          scm_misc_error (NULL, "mutex not locked by current thread", SCM_EOL);
diff --git a/libguile/threads.h b/libguile/threads.h
index 0aef61d..821d27c 100644
--- a/libguile/threads.h
+++ b/libguile/threads.h
@@ -150,7 +150,7 @@ SCM_API SCM scm_thread_p (SCM t);
 
 SCM_API SCM scm_make_mutex (void);
 SCM_API SCM scm_make_recursive_mutex (void);
-SCM_API SCM scm_make_mutex_with_flags (SCM flags);
+SCM_API SCM scm_make_mutex_with_kind (SCM kind);
 SCM_API SCM scm_lock_mutex (SCM m);
 SCM_API SCM scm_lock_mutex_timed (SCM m, SCM timeout, SCM owner);
 SCM_API void scm_dynwind_lock_mutex (SCM mutex);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]