diff options
author | Andy Wingo <wingo@pobox.com> | 2011-12-06 13:50:05 +0100 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2011-12-06 18:01:45 +0100 |
commit | 92c0ebac90439a90b7acc33f3c44f5adf470d8c9 (patch) | |
tree | ef2750edb63da0f6df7622f3c94c8e595f1b7f06 | |
parent | ea0582c283c29e40f1eb1e85821a9c46bc386121 (diff) | |
download | guile-92c0ebac90439a90b7acc33f3c44f5adf470d8c9.tar.gz |
port locking refactor
* libguile/ports.h (struct scm_t_port): Make the lock into a pointer
field instead of an inline field. It should be possible to make
unlocked ports by having a NULL lock field.
(scm_c_lock_port, scm_c_try_lock_port): Return the mutex if the port
was actually locked.
(scm_c_unlock_port): Remove.
* libguile/ports.c (scm_c_make_port_with_encoding): For now, leave
`lock' set to 0.
Change scm_c_lock_port callers to pay attention to the new API.
* libguile/print.c (scm_write, scm_display): Fix call to
dynwind-lock-port for ports-with-print-states.
-rw-r--r-- | libguile/ports.c | 143 | ||||
-rw-r--r-- | libguile/ports.h | 47 | ||||
-rw-r--r-- | libguile/print.c | 4 |
3 files changed, 121 insertions, 73 deletions
diff --git a/libguile/ports.c b/libguile/ports.c index 20c734920..1aa5c6181 100644 --- a/libguile/ports.c +++ b/libguile/ports.c @@ -582,8 +582,10 @@ scm_c_make_port_with_encoding (scm_t_bits tag, unsigned long mode_bits, SCM_SET_CELL_WORD_1 (ret, (scm_t_bits) entry); SCM_SET_CELL_WORD_2 (ret, (scm_t_bits) ptob); -#if SCM_USE_PTHREAD_THREADS - scm_i_pthread_mutex_init (&entry->lock, scm_i_pthread_mutexattr_recursive); + entry->lock = NULL; +#if 0 + entry->lock = scm_gc_malloc_pointerless (sizeof (*entry->lock), "port lock"); + scm_i_pthread_mutex_init (entry->lock, scm_i_pthread_mutexattr_recursive); #endif entry->file_name = SCM_BOOL_F; @@ -1101,25 +1103,31 @@ SCM_DEFINE (scm_set_port_conversion_strategy_x, "set-port-conversion-strategy!", /* The port lock. */ static void -lock_port (SCM port) +lock_port (void *mutex) { - scm_c_lock_port (port); + scm_i_pthread_mutex_lock (mutex); } static void -unlock_port (SCM port) +unlock_port (void *mutex) { - scm_c_unlock_port (port); + scm_i_pthread_mutex_unlock (mutex); } void scm_dynwind_lock_port (SCM port) +#define FUNC_NAME "dynwind-lock-port" { - scm_dynwind_unwind_handler_with_scm (unlock_port, port, - SCM_F_WIND_EXPLICITLY); - scm_dynwind_rewind_handler_with_scm (lock_port, port, - SCM_F_WIND_EXPLICITLY); + scm_i_pthread_mutex_t *lock; + SCM_VALIDATE_OPPORT (SCM_ARG1, port); + scm_c_lock_port (port, &lock); + if (lock) + { + scm_dynwind_unwind_handler (unlock_port, lock, SCM_F_WIND_EXPLICITLY); + scm_dynwind_rewind_handler (lock_port, lock, 0); + } } +#undef FUNC_NAME @@ -1132,11 +1140,13 @@ scm_dynwind_lock_port (SCM port) int scm_revealed_count (SCM port) { + scm_i_pthread_mutex_t *lock; int ret; - scm_c_lock_port (port); + scm_c_lock_port (port, &lock); ret = SCM_REVEALED (port); - scm_c_unlock_port (port); + if (lock) + scm_i_pthread_mutex_unlock (lock); return ret; } @@ -1160,12 +1170,15 @@ SCM_DEFINE (scm_set_port_revealed_x, "set-port-revealed!", 2, 0, 0, #define FUNC_NAME s_scm_set_port_revealed_x { int r; + scm_i_pthread_mutex_t *lock; + port = SCM_COERCE_OUTPORT (port); SCM_VALIDATE_OPENPORT (1, port); r = scm_to_int (rcount); - scm_c_lock_port (port); + scm_c_lock_port (port, &lock); SCM_REVEALED (port) = r; - scm_c_unlock_port (port); + if (lock) + scm_i_pthread_mutex_unlock (lock); return SCM_UNSPECIFIED; } #undef FUNC_NAME @@ -1177,13 +1190,15 @@ SCM_DEFINE (scm_adjust_port_revealed_x, "adjust-port-revealed!", 2, 0, 0, "The return value is unspecified.") #define FUNC_NAME s_scm_set_port_revealed_x { + scm_i_pthread_mutex_t *lock; int a; port = SCM_COERCE_OUTPORT (port); SCM_VALIDATE_OPENPORT (1, port); a = scm_to_int (addend); - scm_c_lock_port (port); + scm_c_lock_port (port, &lock); SCM_REVEALED (port) += a; - scm_c_unlock_port (port); + if (lock) + scm_i_pthread_mutex_unlock (lock); return SCM_UNSPECIFIED; } #undef FUNC_NAME @@ -1196,11 +1211,13 @@ SCM_DEFINE (scm_adjust_port_revealed_x, "adjust-port-revealed!", 2, 0, 0, int scm_get_byte_or_eof (SCM port) { + scm_i_pthread_mutex_t *lock; int ret; - scm_c_lock_port (port); + scm_c_lock_port (port, &lock); ret = scm_get_byte_or_eof_unlocked (port); - scm_c_unlock_port (port); + if (lock) + scm_i_pthread_mutex_unlock (lock); return ret; } @@ -1208,11 +1225,13 @@ scm_get_byte_or_eof (SCM port) int scm_peek_byte_or_eof (SCM port) { + scm_i_pthread_mutex_t *lock; int ret; - scm_c_lock_port (port); + scm_c_lock_port (port, &lock); ret = scm_peek_byte_or_eof_unlocked (port); - scm_c_unlock_port (port); + if (lock) + scm_i_pthread_mutex_unlock (lock); return ret; } @@ -1358,11 +1377,14 @@ scm_c_read_unlocked (SCM port, void *buffer, size_t size) size_t scm_c_read (SCM port, void *buffer, size_t size) { + scm_i_pthread_mutex_t *lock; size_t ret; - scm_c_lock_port (port); + scm_c_lock_port (port, &lock); ret = scm_c_read_unlocked (port, buffer, size); - scm_c_unlock_port (port); + if (lock) + scm_i_pthread_mutex_unlock (lock); + return ret; } @@ -1692,11 +1714,14 @@ scm_getc_unlocked (SCM port) scm_t_wchar scm_getc (SCM port) { + scm_i_pthread_mutex_t *lock; scm_t_wchar ret; - scm_c_lock_port (port); + scm_c_lock_port (port, &lock); ret = scm_getc_unlocked (port); - scm_c_unlock_port (port); + if (lock) + scm_i_pthread_mutex_unlock (lock); + return ret; } @@ -1795,9 +1820,12 @@ scm_unget_byte_unlocked (int c, SCM port) void scm_unget_byte (int c, SCM port) { - scm_c_lock_port (port); + scm_i_pthread_mutex_t *lock; + scm_c_lock_port (port, &lock); scm_unget_byte_unlocked (c, port); - scm_c_unlock_port (port); + if (lock) + scm_i_pthread_mutex_unlock (lock); + } void @@ -1848,9 +1876,12 @@ scm_ungetc_unlocked (scm_t_wchar c, SCM port) void scm_ungetc (scm_t_wchar c, SCM port) { - scm_c_lock_port (port); + scm_i_pthread_mutex_t *lock; + scm_c_lock_port (port, &lock); scm_ungetc_unlocked (c, port); - scm_c_unlock_port (port); + if (lock) + scm_i_pthread_mutex_unlock (lock); + } void @@ -1869,9 +1900,12 @@ scm_ungets_unlocked (const char *s, int n, SCM port) void scm_ungets (const char *s, int n, SCM port) { - scm_c_lock_port (port); + scm_i_pthread_mutex_t *lock; + scm_c_lock_port (port, &lock); scm_ungets_unlocked (s, n, port); - scm_c_unlock_port (port); + if (lock) + scm_i_pthread_mutex_unlock (lock); + } SCM_DEFINE (scm_peek_char, "peek-char", 0, 1, 0, @@ -2022,11 +2056,14 @@ scm_fill_input_unlocked (SCM port) int scm_fill_input (SCM port) { + scm_i_pthread_mutex_t *lock; int ret; - scm_c_lock_port (port); + scm_c_lock_port (port, &lock); ret = scm_fill_input_unlocked (port); - scm_c_unlock_port (port); + if (lock) + scm_i_pthread_mutex_unlock (lock); + return ret; } @@ -2128,9 +2165,12 @@ scm_end_input_unlocked (SCM port) void scm_end_input (SCM port) { - scm_c_lock_port (port); + scm_i_pthread_mutex_t *lock; + scm_c_lock_port (port, &lock); scm_end_input_unlocked (port); - scm_c_unlock_port (port); + if (lock) + scm_i_pthread_mutex_unlock (lock); + } SCM_DEFINE (scm_force_output, "force-output", 0, 1, 0, @@ -2164,9 +2204,12 @@ scm_flush_unlocked (SCM port) void scm_flush (SCM port) { - scm_c_lock_port (port); + scm_i_pthread_mutex_t *lock; + scm_c_lock_port (port, &lock); scm_flush_unlocked (port); - scm_c_unlock_port (port); + if (lock) + scm_i_pthread_mutex_unlock (lock); + } @@ -2177,17 +2220,23 @@ scm_flush (SCM port) void scm_putc (char c, SCM port) { - scm_c_lock_port (port); + scm_i_pthread_mutex_t *lock; + scm_c_lock_port (port, &lock); scm_putc_unlocked (c, port); - scm_c_unlock_port (port); + if (lock) + scm_i_pthread_mutex_unlock (lock); + } void scm_puts (const char *s, SCM port) { - scm_c_lock_port (port); + scm_i_pthread_mutex_t *lock; + scm_c_lock_port (port, &lock); scm_puts_unlocked (s, port); - scm_c_unlock_port (port); + if (lock) + scm_i_pthread_mutex_unlock (lock); + } /* scm_c_write @@ -2224,9 +2273,12 @@ scm_c_write_unlocked (SCM port, const void *ptr, size_t size) void scm_c_write (SCM port, const void *ptr, size_t size) { - scm_c_lock_port (port); + scm_i_pthread_mutex_t *lock; + scm_c_lock_port (port, &lock); scm_c_write_unlocked (port, ptr, size); - scm_c_unlock_port (port); + if (lock) + scm_i_pthread_mutex_unlock (lock); + } /* scm_lfwrite @@ -2254,9 +2306,12 @@ scm_lfwrite_unlocked (const char *ptr, size_t size, SCM port) void scm_lfwrite (const char *ptr, size_t size, SCM port) { - scm_c_lock_port (port); + scm_i_pthread_mutex_t *lock; + scm_c_lock_port (port, &lock); scm_lfwrite_unlocked (ptr, size, port); - scm_c_unlock_port (port); + if (lock) + scm_i_pthread_mutex_unlock (lock); + } /* Write STR to PORT from START inclusive to END exclusive. */ diff --git a/libguile/ports.h b/libguile/ports.h index b6db482b2..8c578a6df 100644 --- a/libguile/ports.h +++ b/libguile/ports.h @@ -53,9 +53,7 @@ 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 + scm_i_pthread_mutex_t *lock; /* A recursive lock for this port. */ int revealed; /* 0 not revealed, > 1 revealed. * Revealed ports do not get GC'd. @@ -295,9 +293,8 @@ SCM_API SCM scm_set_port_conversion_strategy_x (SCM port, SCM behavior); /* Acquiring and releasing the port lock. */ SCM_API void scm_dynwind_lock_port (SCM port); -SCM_INLINE int scm_c_lock_port (SCM port); -SCM_INLINE int scm_c_try_lock_port (SCM port); -SCM_INLINE int scm_c_unlock_port (SCM port); +SCM_INLINE int scm_c_lock_port (SCM port, scm_i_pthread_mutex_t **lock); +SCM_INLINE int scm_c_try_lock_port (SCM port, scm_i_pthread_mutex_t **lock); /* Revealed counts. */ SCM_API int scm_revealed_count (SCM port); @@ -383,33 +380,29 @@ SCM_INTERNAL void scm_init_ports (void); #if SCM_CAN_INLINE || defined SCM_INLINE_C_IMPLEMENTING_INLINES SCM_INLINE_IMPLEMENTATION int -scm_c_lock_port (SCM port) +scm_c_lock_port (SCM port, scm_i_pthread_mutex_t **lock) { -#if 0 && SCM_USE_PTHREAD_THREADS - return scm_i_pthread_mutex_lock (&SCM_PTAB_ENTRY (port)->lock); -#else - return 0; -#endif -} + *lock = SCM_PTAB_ENTRY (port)->lock; -SCM_INLINE_IMPLEMENTATION int -scm_c_try_lock_port (SCM port) -{ -#if 0 && SCM_USE_PTHREAD_THREADS - return scm_i_pthread_mutex_trylock (&SCM_PTAB_ENTRY (port)->lock); -#else - return 0; -#endif + if (*lock) + return scm_i_pthread_mutex_lock (*lock); + else + return 0; } SCM_INLINE_IMPLEMENTATION int -scm_c_unlock_port (SCM port) +scm_c_try_lock_port (SCM port, scm_i_pthread_mutex_t **lock) { -#if 0 && SCM_USE_PTHREAD_THREADS - return scm_i_pthread_mutex_unlock (&SCM_PTAB_ENTRY (port)->lock); -#else - return 0; -#endif + *lock = SCM_PTAB_ENTRY (port)->lock; + if (*lock) + { + int ret = scm_i_pthread_mutex_trylock (*lock); + if (ret != 0) + *lock = NULL; + return ret; + } + else + return 0; } SCM_INLINE_IMPLEMENTATION int diff --git a/libguile/print.c b/libguile/print.c index 030ea6908..cdb923793 100644 --- a/libguile/print.c +++ b/libguile/print.c @@ -1295,7 +1295,7 @@ scm_write (SCM obj, SCM port) SCM_ASSERT (scm_valid_oport_value_p (port), port, SCM_ARG2, s_write); scm_dynwind_begin (0); - scm_dynwind_lock_port (port); + scm_dynwind_lock_port (SCM_COERCE_OUTPORT (port)); scm_prin1 (obj, port, 1); scm_dynwind_end (); @@ -1314,7 +1314,7 @@ scm_display (SCM obj, SCM port) SCM_ASSERT (scm_valid_oport_value_p (port), port, SCM_ARG2, s_display); scm_dynwind_begin (0); - scm_dynwind_lock_port (port); + scm_dynwind_lock_port (SCM_COERCE_OUTPORT (port)); scm_prin1 (obj, port, 0); scm_dynwind_end (); |