diff --git a/ChangeLog b/ChangeLog index 2a00a888..aeb27fab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -25,6 +25,10 @@ Paul Davis Jackdmp changes log --------------------------- +2009-11-13 Stephane Letz + + * Better memory allocation error checking in ringbuffer.c, weak import improvements. + 2009-11-12 Stephane Letz * Better memory allocation error checking on client (library) side. diff --git a/common/JackWeakAPI.cpp b/common/JackWeakAPI.cpp index 84a032dc..b4607e6c 100644 --- a/common/JackWeakAPI.cpp +++ b/common/JackWeakAPI.cpp @@ -21,7 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Completed from Julien Pommier (PianoTeq : http://www.pianoteq.com/) code. */ -#include "jack.h" +#include #include #include #include @@ -81,7 +81,7 @@ DECL_FUNCTION(const char *, jack_get_version_string, (), ()); DECL_FUNCTION(jack_client_t *, jack_client_open, (const char *client_name, jack_options_t options, jack_status_t *status, ...), (client_name, options, status)); DECL_FUNCTION(int, jack_client_close, (jack_client_t *client), (client)); -DECL_FUNCTION(int, jack_client_new, (const char *client_name), (client_name)); +DECL_FUNCTION(jack_client_t *, jack_client_new, (const char *client_name), (client_name)); DECL_FUNCTION(int, jack_client_name_size, (), ()); DECL_FUNCTION(char*, jack_get_client_name, (jack_client_t *client), (client)); DECL_FUNCTION(int, jack_internal_client_new, (const char *client_name, @@ -89,8 +89,8 @@ DECL_FUNCTION(int, jack_internal_client_new, (const char *client_name, const char *load_init), (client_name, load_name, load_init)); DECL_VOID_FUNCTION(jack_internal_client_close, (const char *client_name), (client_name)); DECL_FUNCTION(int, jack_is_realtime, (jack_client_t *client), (client)); -DECL_VOID_FUNCTION(jack_on_shutdown, (jack_client_t *client, JackShutdownCallback shutdown_callback, void *arg), (client, function, arg)); -DECL_VOID_FUNCTION(jack_on_info_shutdown, (jack_client_t* ext_client, JackInfoShutdownCallback callback, void* arg, (client, function, arg)) +DECL_VOID_FUNCTION(jack_on_shutdown, (jack_client_t *client, JackShutdownCallback shutdown_callback, void *arg), (client, shutdown_callback, arg)); +DECL_VOID_FUNCTION(jack_on_info_shutdown, (jack_client_t* client, JackInfoShutdownCallback shutdown_callback, void* arg), (client, shutdown_callback, arg)); DECL_FUNCTION(int, jack_set_process_callback, (jack_client_t *client, JackProcessCallback process_callback, void *arg), (client, process_callback, arg)); @@ -98,7 +98,7 @@ DECL_FUNCTION(jack_nframes_t, jack_thread_wait, (jack_client_t *client, int stat // DECL_FUNCTION(jack_nframes_t, jack_cycle_wait, (jack_client_t *client), (client)); -DECL_VOID_FUNCTION(jack_cycle_signal, (jack_client_t *client, , int status), (client, status)); +DECL_VOID_FUNCTION(jack_cycle_signal, (jack_client_t *client, int status), (client, status)); DECL_FUNCTION(int, jack_set_process_thread, (jack_client_t *client, JackThreadCallback fun, void *arg), (client, fun, arg)); @@ -153,11 +153,11 @@ DECL_FUNCTION(const char**, jack_port_get_connections, (const jack_port_t *port) DECL_FUNCTION(const char**, jack_port_get_all_connections, (const jack_port_t *port), (port)); DECL_FUNCTION(int, jack_port_tie, (jack_port_t *src, jack_port_t *dst), (src, dst)); DECL_FUNCTION(int, jack_port_untie, (jack_port_t *port), (port)); -DECL_FUNCTION(jack_nframes_t, jack_port_get_latency, (jack_port_t *port)); +DECL_FUNCTION(jack_nframes_t, jack_port_get_latency, (jack_client_t *), (jack_port_t *port)); DECL_FUNCTION(jack_nframes_t, jack_port_get_total_latency ,(jack_client_t *), (jack_port_t *port)); DECL_VOID_FUNCTION(jack_port_set_latency, (jack_port_t *), (jack_nframes_t)); DECL_FUNCTION(int, jack_recompute_total_latency, (jack_client_t*), (jack_port_t* port)); -DECL_FUNCTION(int, jack_recompute_total_latencies, (jack_client_t*)); +DECL_FUNCTION(int, jack_recompute_total_latencies, (jack_client_t*),(client)); DECL_FUNCTION(int, jack_port_set_name, (jack_port_t *port), (const char *port_name)); DECL_FUNCTION(int, jack_port_set_alias, (jack_port_t *port), (const char *alias)); @@ -239,5 +239,5 @@ DECL_FUNCTION(int jack_midi_event_get(jack_midi_event_t* event, void* port_buffe DECL_VOID_FUNCTION(jack_midi_clear_buffer, (void* port_buffer)); DECL_FUNCTION(size_t, jack_midi_max_event_size, (void* port_buffer)); DECL_FUNCTION(jack_midi_data_t*, jack_midi_event_reserve, (void* port_buffer), (jack_nframes_t time), (size_t data_size)); -DECL_FUNCTIO(int jack_midi_event_write, (void* port_buffer), (jack_nframes_t time), (const jack_midi_data_t* data), (size_t data_size)); +DECL_FUNCTION(int jack_midi_event_write, (void* port_buffer), (jack_nframes_t time), (const jack_midi_data_t* data), (size_t data_size)); DECL_FUNCTION(jack_nframes_t, jack_midi_get_lost_event_count, (void* port_buffer)); diff --git a/common/jack/jack.h b/common/jack/jack.h index a59299dc..a5dc3aec 100644 --- a/common/jack/jack.h +++ b/common/jack/jack.h @@ -34,6 +34,25 @@ extern "C" * Note: More documentation can be found in jack/types.h. */ +/************************************************************* + * NOTE: JACK_WEAK_EXPORT ***MUST*** be used on every function + * added to the JACK API after the 0.116.2 release. + *************************************************************/ + +#ifndef JACK_WEAK_EXPORT +#ifdef __GNUC__ +/* JACK_WEAK_EXPORT needs to be a macro which + expands into a compiler directive. If non-null, the directive + must tell the compiler to arrange for weak linkage of + the symbol it used with. For this to work full may + require linker arguments in the client as well. +*/ +#define JACK_WEAK_EXPORT __attribute__((weak)) +#else +/* Add other things here for non-gcc platforms */ +#endif +#endif + /** * @defgroup ClientFunctions Creating & manipulating clients * @{ @@ -301,7 +320,7 @@ int jack_set_thread_init_callback (jack_client_t *client, * jack_on_info_shutdown() will. */ void jack_on_shutdown (jack_client_t *client, - JackShutdownCallback shutdown_callback, void *arg); + JackShutdownCallback shutdown_callback, void *arg) JACK_WEAK_EXPORT; /** * @param client pointer to JACK client structure. diff --git a/common/ringbuffer.c b/common/ringbuffer.c index a7209a2b..f7bc9658 100644 --- a/common/ringbuffer.c +++ b/common/ringbuffer.c @@ -64,252 +64,244 @@ size_t jack_ringbuffer_write_space(const jack_ringbuffer_t *rb); /* Create a new ringbuffer to hold at least `sz' bytes of data. The actual buffer size is rounded up to the next power of two. */ -EXPORT jack_ringbuffer_t * +jack_ringbuffer_t * jack_ringbuffer_create (size_t sz) { - int power_of_two; - jack_ringbuffer_t *rb; - - rb = (jack_ringbuffer_t*)malloc (sizeof (jack_ringbuffer_t)); - - for (power_of_two = 1; 1 << power_of_two < sz; power_of_two++); - - rb->size = 1 << power_of_two; - rb->size_mask = rb->size; - rb->size_mask -= 1; - rb->write_ptr = 0; - rb->read_ptr = 0; - rb->buf = (char*)malloc (rb->size); - memset(rb->buf, 0, rb->size); - rb->mlocked = 0; - - return rb; + int power_of_two; + jack_ringbuffer_t *rb; + + if ((rb = malloc (sizeof (jack_ringbuffer_t))) == NULL) { + return NULL; + } + + for (power_of_two = 1; 1 << power_of_two < sz; power_of_two++); + + rb->size = 1 << power_of_two; + rb->size_mask = rb->size; + rb->size_mask -= 1; + rb->write_ptr = 0; + rb->read_ptr = 0; + if ((rb->buf = malloc (rb->size)) == NULL) { + free (rb); + return NULL; + } + rb->mlocked = 0; + + return rb; } /* Free all data associated with the ringbuffer `rb'. */ -EXPORT void +void jack_ringbuffer_free (jack_ringbuffer_t * rb) { #ifdef USE_MLOCK - if (rb->mlocked) { - munlock (rb->buf, rb->size); - } + if (rb->mlocked) { + munlock (rb->buf, rb->size); + } #endif /* USE_MLOCK */ - free (rb->buf); - free (rb); + free (rb->buf); + free (rb); } /* Lock the data block of `rb' using the system call 'mlock'. */ -EXPORT int +int jack_ringbuffer_mlock (jack_ringbuffer_t * rb) { #ifdef USE_MLOCK - if (mlock (rb->buf, rb->size)) { - return -1; - } + if (mlock (rb->buf, rb->size)) { + return -1; + } #endif /* USE_MLOCK */ - rb->mlocked = 1; - return 0; + rb->mlocked = 1; + return 0; } /* Reset the read and write pointers to zero. This is not thread safe. */ -EXPORT void +void jack_ringbuffer_reset (jack_ringbuffer_t * rb) { - rb->read_ptr = 0; - rb->write_ptr = 0; -} - -/* Reset the read and write pointers to zero. This is not thread - safe. */ - -EXPORT void -jack_ringbuffer_reset_size (jack_ringbuffer_t * rb, size_t sz) -{ - rb->size = sz; - rb->size_mask = rb->size; - rb->size_mask -= 1; - rb->read_ptr = 0; - rb->write_ptr = 0; + rb->read_ptr = 0; + rb->write_ptr = 0; } /* Return the number of bytes available for reading. This is the number of bytes in front of the read pointer and behind the write pointer. */ -EXPORT size_t +size_t jack_ringbuffer_read_space (const jack_ringbuffer_t * rb) { - size_t w, r; - - w = rb->write_ptr; - r = rb->read_ptr; - - if (w > r) { - return w - r; - } else { - return (w - r + rb->size) & rb->size_mask; - } + size_t w, r; + + w = rb->write_ptr; + r = rb->read_ptr; + + if (w > r) { + return w - r; + } else { + return (w - r + rb->size) & rb->size_mask; + } } /* Return the number of bytes available for writing. This is the number of bytes in front of the write pointer and behind the read pointer. */ -EXPORT size_t +size_t jack_ringbuffer_write_space (const jack_ringbuffer_t * rb) { - size_t w, r; - - w = rb->write_ptr; - r = rb->read_ptr; - - if (w > r) { - return ((r - w + rb->size) & rb->size_mask) - 1; - } else if (w < r) { - return (r - w) - 1; - } else { - return rb->size - 1; - } + size_t w, r; + + w = rb->write_ptr; + r = rb->read_ptr; + + if (w > r) { + return ((r - w + rb->size) & rb->size_mask) - 1; + } else if (w < r) { + return (r - w) - 1; + } else { + return rb->size - 1; + } } /* The copying data reader. Copy at most `cnt' bytes from `rb' to `dest'. Returns the actual number of bytes copied. */ -EXPORT size_t +size_t jack_ringbuffer_read (jack_ringbuffer_t * rb, char *dest, size_t cnt) { - size_t free_cnt; - size_t cnt2; - size_t to_read; - size_t n1, n2; + size_t free_cnt; + size_t cnt2; + size_t to_read; + size_t n1, n2; - if ((free_cnt = jack_ringbuffer_read_space (rb)) == 0) { - return 0; - } + if ((free_cnt = jack_ringbuffer_read_space (rb)) == 0) { + return 0; + } - to_read = cnt > free_cnt ? free_cnt : cnt; + to_read = cnt > free_cnt ? free_cnt : cnt; - cnt2 = rb->read_ptr + to_read; + cnt2 = rb->read_ptr + to_read; - if (cnt2 > rb->size) { - n1 = rb->size - rb->read_ptr; - n2 = cnt2 & rb->size_mask; - } else { - n1 = to_read; - n2 = 0; - } + if (cnt2 > rb->size) { + n1 = rb->size - rb->read_ptr; + n2 = cnt2 & rb->size_mask; + } else { + n1 = to_read; + n2 = 0; + } - memcpy (dest, &(rb->buf[rb->read_ptr]), n1); - rb->read_ptr = (rb->read_ptr + n1) & rb->size_mask; + memcpy (dest, &(rb->buf[rb->read_ptr]), n1); + rb->read_ptr = (rb->read_ptr + n1) & rb->size_mask; - if (n2) { - memcpy (dest + n1, &(rb->buf[rb->read_ptr]), n2); - rb->read_ptr = (rb->read_ptr + n2) & rb->size_mask; - } + if (n2) { + memcpy (dest + n1, &(rb->buf[rb->read_ptr]), n2); + rb->read_ptr = (rb->read_ptr + n2) & rb->size_mask; + } - return to_read; + return to_read; } -/* The copying data reader w/o read pointer advance. Copy at most - `cnt' bytes from `rb' to `dest'. Returns the actual number of bytes -copied. */ +/* The copying data reader w/o read pointer advance. Copy at most + `cnt' bytes from `rb' to `dest'. Returns the actual number of bytes + copied. */ -EXPORT size_t +size_t jack_ringbuffer_peek (jack_ringbuffer_t * rb, char *dest, size_t cnt) { - size_t free_cnt; - size_t cnt2; - size_t to_read; - size_t n1, n2; - size_t tmp_read_ptr; + size_t free_cnt; + size_t cnt2; + size_t to_read; + size_t n1, n2; + size_t tmp_read_ptr; - tmp_read_ptr = rb->read_ptr; + tmp_read_ptr = rb->read_ptr; - if ((free_cnt = jack_ringbuffer_read_space (rb)) == 0) { - return 0; - } + if ((free_cnt = jack_ringbuffer_read_space (rb)) == 0) { + return 0; + } - to_read = cnt > free_cnt ? free_cnt : cnt; + to_read = cnt > free_cnt ? free_cnt : cnt; - cnt2 = tmp_read_ptr + to_read; + cnt2 = tmp_read_ptr + to_read; - if (cnt2 > rb->size) { - n1 = rb->size - tmp_read_ptr; - n2 = cnt2 & rb->size_mask; - } else { - n1 = to_read; - n2 = 0; - } + if (cnt2 > rb->size) { + n1 = rb->size - tmp_read_ptr; + n2 = cnt2 & rb->size_mask; + } else { + n1 = to_read; + n2 = 0; + } - memcpy (dest, &(rb->buf[tmp_read_ptr]), n1); - tmp_read_ptr = (tmp_read_ptr + n1) & rb->size_mask; + memcpy (dest, &(rb->buf[tmp_read_ptr]), n1); + tmp_read_ptr = (tmp_read_ptr + n1) & rb->size_mask; - if (n2) { - memcpy (dest + n1, &(rb->buf[tmp_read_ptr]), n2); - } + if (n2) { + memcpy (dest + n1, &(rb->buf[tmp_read_ptr]), n2); + } - return to_read; + return to_read; } + /* The copying data writer. Copy at most `cnt' bytes to `rb' from `src'. Returns the actual number of bytes copied. */ -EXPORT size_t +size_t jack_ringbuffer_write (jack_ringbuffer_t * rb, const char *src, size_t cnt) { - size_t free_cnt; - size_t cnt2; - size_t to_write; - size_t n1, n2; + size_t free_cnt; + size_t cnt2; + size_t to_write; + size_t n1, n2; - if ((free_cnt = jack_ringbuffer_write_space (rb)) == 0) { - return 0; - } + if ((free_cnt = jack_ringbuffer_write_space (rb)) == 0) { + return 0; + } - to_write = cnt > free_cnt ? free_cnt : cnt; + to_write = cnt > free_cnt ? free_cnt : cnt; - cnt2 = rb->write_ptr + to_write; + cnt2 = rb->write_ptr + to_write; - if (cnt2 > rb->size) { - n1 = rb->size - rb->write_ptr; - n2 = cnt2 & rb->size_mask; - } else { - n1 = to_write; - n2 = 0; - } + if (cnt2 > rb->size) { + n1 = rb->size - rb->write_ptr; + n2 = cnt2 & rb->size_mask; + } else { + n1 = to_write; + n2 = 0; + } - memcpy (&(rb->buf[rb->write_ptr]), src, n1); - rb->write_ptr = (rb->write_ptr + n1) & rb->size_mask; + memcpy (&(rb->buf[rb->write_ptr]), src, n1); + rb->write_ptr = (rb->write_ptr + n1) & rb->size_mask; - if (n2) { - memcpy (&(rb->buf[rb->write_ptr]), src + n1, n2); - rb->write_ptr = (rb->write_ptr + n2) & rb->size_mask; - } + if (n2) { + memcpy (&(rb->buf[rb->write_ptr]), src + n1, n2); + rb->write_ptr = (rb->write_ptr + n2) & rb->size_mask; + } - return to_write; + return to_write; } /* Advance the read pointer `cnt' places. */ -EXPORT void +void jack_ringbuffer_read_advance (jack_ringbuffer_t * rb, size_t cnt) { - size_t tmp = (rb->read_ptr + cnt) & rb->size_mask; - rb->read_ptr = tmp; + size_t tmp = (rb->read_ptr + cnt) & rb->size_mask; + rb->read_ptr = tmp; } /* Advance the write pointer `cnt' places. */ -EXPORT void +void jack_ringbuffer_write_advance (jack_ringbuffer_t * rb, size_t cnt) { - size_t tmp = (rb->write_ptr + cnt) & rb->size_mask; - rb->write_ptr = tmp; + size_t tmp = (rb->write_ptr + cnt) & rb->size_mask; + rb->write_ptr = tmp; } /* The non-copying data reader. `vec' is an array of two places. Set @@ -317,43 +309,43 @@ jack_ringbuffer_write_advance (jack_ringbuffer_t * rb, size_t cnt) the readable data is in one segment the second segment has zero length. */ -EXPORT void +void jack_ringbuffer_get_read_vector (const jack_ringbuffer_t * rb, jack_ringbuffer_data_t * vec) { - size_t free_cnt; - size_t cnt2; - size_t w, r; + size_t free_cnt; + size_t cnt2; + size_t w, r; - w = rb->write_ptr; - r = rb->read_ptr; + w = rb->write_ptr; + r = rb->read_ptr; - if (w > r) { - free_cnt = w - r; - } else { - free_cnt = (w - r + rb->size) & rb->size_mask; - } + if (w > r) { + free_cnt = w - r; + } else { + free_cnt = (w - r + rb->size) & rb->size_mask; + } - cnt2 = r + free_cnt; + cnt2 = r + free_cnt; - if (cnt2 > rb->size) { + if (cnt2 > rb->size) { - /* Two part vector: the rest of the buffer after the current write - ptr, plus some from the start of the buffer. */ + /* Two part vector: the rest of the buffer after the current write + ptr, plus some from the start of the buffer. */ - vec[0].buf = &(rb->buf[r]); - vec[0].len = rb->size - r; - vec[1].buf = rb->buf; - vec[1].len = cnt2 & rb->size_mask; + vec[0].buf = &(rb->buf[r]); + vec[0].len = rb->size - r; + vec[1].buf = rb->buf; + vec[1].len = cnt2 & rb->size_mask; - } else { + } else { - /* Single part vector: just the rest of the buffer */ + /* Single part vector: just the rest of the buffer */ - vec[0].buf = &(rb->buf[r]); - vec[0].len = free_cnt; - vec[1].len = 0; - } + vec[0].buf = &(rb->buf[r]); + vec[0].len = free_cnt; + vec[1].len = 0; + } } /* The non-copying data writer. `vec' is an array of two places. Set @@ -361,39 +353,39 @@ jack_ringbuffer_get_read_vector (const jack_ringbuffer_t * rb, the writeable data is in one segment the second segment has zero length. */ -EXPORT void +void jack_ringbuffer_get_write_vector (const jack_ringbuffer_t * rb, jack_ringbuffer_data_t * vec) { - size_t free_cnt; - size_t cnt2; - size_t w, r; - - w = rb->write_ptr; - r = rb->read_ptr; - - if (w > r) { - free_cnt = ((r - w + rb->size) & rb->size_mask) - 1; - } else if (w < r) { - free_cnt = (r - w) - 1; - } else { - free_cnt = rb->size - 1; - } - - cnt2 = w + free_cnt; - - if (cnt2 > rb->size) { - - /* Two part vector: the rest of the buffer after the current write - ptr, plus some from the start of the buffer. */ - - vec[0].buf = &(rb->buf[w]); - vec[0].len = rb->size - w; - vec[1].buf = rb->buf; - vec[1].len = cnt2 & rb->size_mask; - } else { - vec[0].buf = &(rb->buf[w]); - vec[0].len = free_cnt; - vec[1].len = 0; - } -} + size_t free_cnt; + size_t cnt2; + size_t w, r; + + w = rb->write_ptr; + r = rb->read_ptr; + + if (w > r) { + free_cnt = ((r - w + rb->size) & rb->size_mask) - 1; + } else if (w < r) { + free_cnt = (r - w) - 1; + } else { + free_cnt = rb->size - 1; + } + + cnt2 = w + free_cnt; + + if (cnt2 > rb->size) { + + /* Two part vector: the rest of the buffer after the current write + ptr, plus some from the start of the buffer. */ + + vec[0].buf = &(rb->buf[w]); + vec[0].len = rb->size - w; + vec[1].buf = rb->buf; + vec[1].len = cnt2 & rb->size_mask; + } else { + vec[0].buf = &(rb->buf[w]); + vec[0].len = free_cnt; + vec[1].len = 0; + } +} \ No newline at end of file