summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2011-11-07 16:01:01 +0100
committerAndy Wingo <wingo@pobox.com>2011-11-07 16:01:01 +0100
commit30b126d2bad540f1f508917214467529cb05a3d3 (patch)
tree4c1c19814c2e576832be64e5ce17c042aa049429
parent0f9f51a153db3e669a12c416c4958d71bd3c2a8b (diff)
downloadguile-30b126d2bad540f1f508917214467529cb05a3d3.tar.gz
add lock to scm_t_port
* libguile/ports.h (scm_c_lock_port, scm_c_try_lock_port) (scm_c_unlock_port): New inline functions. (scm_t_port): Add a lock field, if threads are enabled. This is a first step towards threadsafe ports. * libguile/ports.c (scm_c_make_port_with_encoding): Init the port's lock. * libguile/inline.c: Residualize the inline functions from ports.h.
-rw-r--r--libguile/inline.c1
-rw-r--r--libguile/ports.c4
-rw-r--r--libguile/ports.h40
3 files changed, 45 insertions, 0 deletions
diff --git a/libguile/inline.c b/libguile/inline.c
index be7670ad7..7b900f71a 100644
--- a/libguile/inline.c
+++ b/libguile/inline.c
@@ -25,3 +25,4 @@
#include "libguile/inline.h"
#include "libguile/gc.h"
#include "libguile/smob.h"
+#include "libguile/ports.h"
diff --git a/libguile/ports.c b/libguile/ports.c
index b6b3aa955..cffc8c8d9 100644
--- a/libguile/ports.c
+++ b/libguile/ports.c
@@ -590,6 +590,10 @@ scm_c_make_port_with_encoding (scm_t_bits tag, unsigned long mode_bits,
entry = (scm_t_port *) scm_gc_calloc (sizeof (scm_t_port), "port");
ret = scm_cell (tag | mode_bits, (scm_t_bits)entry);
+#if SCM_USE_PTHREAD_THREADS
+ scm_i_pthread_mutex_init (&entry->lock, scm_i_pthread_mutexattr_recursive);
+#endif
+
entry->file_name = SCM_BOOL_F;
entry->rw_active = SCM_PORT_NEITHER;
entry->port = ret;
diff --git a/libguile/ports.h b/libguile/ports.h
index f8bff355b..d76bf3c8a 100644
--- a/libguile/ports.h
+++ b/libguile/ports.h
@@ -48,6 +48,10 @@ typedef enum scm_t_port_rw_active {
typedef struct
{
SCM port; /* Link back to the port object. */
+#if SCM_USE_PTHREAD_THREADS
+ scm_i_pthread_mutex_t lock; /* A recursive lock for this port. */
+#endif
+
int revealed; /* 0 not revealed, > 1 revealed.
* Revealed ports do not get GC'd.
*/
@@ -259,6 +263,42 @@ scm_c_make_port_with_encoding (scm_t_bits tag,
SCM_API SCM scm_c_make_port (scm_t_bits tag, unsigned long mode_bits,
scm_t_bits stream);
+SCM_INLINE int scm_c_lock_port (scm_t_port *entry);
+SCM_INLINE int scm_c_try_lock_port (scm_t_port *entry);
+SCM_INLINE int scm_c_unlock_port (scm_t_port *entry);
+
+#if SCM_CAN_INLINE || defined SCM_INLINE_C_IMPLEMENTING_INLINES
+SCM_INLINE_IMPLEMENTATION int
+scm_c_lock_port (scm_t_port *entry)
+{
+#if SCM_USE_PTHREAD_THREADS
+ return scm_i_pthread_mutex_lock (&entry->lock);
+#else
+ return 0;
+#endif
+}
+
+SCM_INLINE_IMPLEMENTATION int
+scm_c_try_lock_port (scm_t_port *entry)
+{
+#if SCM_USE_PTHREAD_THREADS
+ return scm_i_pthread_mutex_trylock (&entry->lock);
+#else
+ return 0;
+#endif
+}
+
+SCM_INLINE_IMPLEMENTATION int
+scm_c_unlock_port (scm_t_port *entry)
+{
+#if SCM_USE_PTHREAD_THREADS
+ return scm_i_pthread_mutex_unlock (&entry->lock);
+#else
+ return 0;
+#endif
+}
+#endif
+
SCM_API SCM scm_new_port_table_entry (scm_t_bits tag);
SCM_API void scm_grow_port_cbuf (SCM port, size_t requested);
SCM_API SCM scm_pt_size (void);