summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);