From: Andre Noll Date: Sat, 18 May 2013 12:06:22 +0000 (+0200) Subject: Merge branch 't/sched_improvements' X-Git-Tag: v0.4.13~39 X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=commitdiff_plain;h=2f07d34b5d4c37606be5849b6ee51e0443707898;hp=-c Merge branch 't/sched_improvements' This topic has been cooking for a month. During this period, one problem on BSD has been found and fixed. 3ad5b0 Fix build on FreeBSD 484e75 sched: Rename new_post_select back to post_select. 74c880 sched: Kill old ->post_select variant. c77e19 grab client: Switch to the alternative post select method. 38aeac client supervisor: Switch to the alternative post select method. e009fa client exec: Switch to the alternative post select method. 742718 i9e: Switch to the alternative post select method. 2e6b8f vss: Switch to the alternative post select method. 6e83b4 stdout: Switch to the alternative post select method. 1995ce stdin: Switch to the alternative post select method. 88b0ec audioc: Switch to the alternative post select method. b210e8 afs command task: Switch to the alternative post select method. 12f683 afs signal task: Switch to the alternative post select method. ccef24 server signal task: Switch to the alternative post select method. a6dabd server command task: Switch to the alternative post select method. 855c53 write: Switch to the alternative post select method. 58b74b play: Switch to the alternative post select method. cf4982 afh_recv: Switch to the alternative post select method. 4dc05b client: Switch to the alternative post select method. 043fd6 audiod: Switch command_task to the alternative post select method. ce462a audiod: Switch the status task to the alternative post select method. a7f2d1 audiod: Switch signal task to the alternative post select method. ba2f65 osx writer: Switch to the alternative post select method. 3642d2 oss writer: Switch to the alternative post select method. c29db3 file writer: Switch to the alternative post select method. 36875c ao: Switch to the alternative post select method. 3b3049 alsa: Switch to the alternative post select method. 60b853 wmadec: Switch to the alternative post select method. 6c8719 wav filter: Switch to the alternative post select method. 03e915 spxdec: Switch to the alternative post select method. 24bbc5 resample: Switch to the alternative post select method. 4ca80f prebuffer: Switch to the alternative post select method. a55083 oggdec: Switch to the alternative post select method. 806d26 mp3dec: Switch to the alternative post select method. 7dcaf5 flacdec: Switch to the alternative post select method. 4dc9b9 fecdec: Switch to the alternative post select method. f6e2cb compress: Switch to the alternative post select method. ac3371 amp: Switch to the alternative post select method. 7c2c68 aacdec: Switch to the alternative post select method. b333e0 dccp_recv: Switch to the alternative post select method. 00e793 udp_recv: Switch to the alternative post select method. 9c00a7 sched: Provide alternative post_select variant. 24758c Replace gettimeofday() by clock_gettime(). 01f802 sched: Get rid of (pre)select shortcuts. 5bb44a audiod: Avoid delay when closing slot. Conflicts: string.c --- 2f07d34b5d4c37606be5849b6ee51e0443707898 diff --combined Makefile.in index 173b81a3,7ccd970d..fa2e468f --- a/Makefile.in +++ b/Makefile.in @@@ -79,6 -79,8 +79,8 @@@ CPPFLAGS += -I/usr/local/includ CPPFLAGS += -I$(cmdline_dir) CPPFLAGS += @osl_cppflags@ + LDFLAGS += @clock_gettime_ldflags@ + man_pages := $(patsubst %, $(man_dir)/%.1, @executables@) autocrap := config.h.in configure @@@ -256,7 -258,7 +258,7 @@@ para_client: $(client_objs para_gui: $(gui_objs) @[ -z "$(Q)" ] || echo 'LD $@' - $(Q) $(CC) $(LDFLAGS) -o $@ $(gui_objs) -lcurses + $(Q) $(CC) $(LDFLAGS) -o $@ $(gui_objs) @gui_ldflags@ para_audiod: $(audiod_objs) @[ -z "$(Q)" ] || echo 'LD $@' diff --combined NEWS index 591d935d,f323df1d..56f84753 --- a/NEWS +++ b/NEWS @@@ -2,8 -2,6 +2,11 @@@ 0.?.? (to be announced) "spectral gravity" ------------------------------------------ + - UTF8 support for para_gui and the mp3 audio format handler. ++ - Scheduler improvements and fixes. ++ - The obsolete gettimeofday() function has been replaced ++ by clock_gettime() on systems which support it. + ----------------------------------------- 0.4.12 (2012-12-20) "volatile relativity" ----------------------------------------- diff --combined aacdec_filter.c index 79e66620,9eea045c..3ff90834 --- a/aacdec_filter.c +++ b/aacdec_filter.c @@@ -80,7 -80,7 +80,7 @@@ static void aacdec_close(struct filter_ fn->private_data = NULL; } - static void aacdec_post_select(__a_unused struct sched *s, struct task *t) + static int aacdec_post_select(__a_unused struct sched *s, struct task *t) { struct filter_node *fn = container_of(t, struct filter_node, task); struct btr_node *btrn = fn->btrn; @@@ -91,12 -91,11 +91,11 @@@ size_t len, skip, consumed, loaded; next_buffer: - t->error = 0; ret = btr_node_status(btrn, fn->min_iqs, BTR_NT_INTERNAL); if (ret < 0) goto err; if (ret == 0) - return; + return 0; btr_merge(btrn, fn->min_iqs); len = btr_next_buffer(btrn, (char **)&inbuf); len = PARA_MIN(len, (size_t)8192); @@@ -123,7 -122,7 +122,7 @@@ ret = -E_AACDEC_INIT; if (NeAACDecInit2(padd->handle, p, padd->decoder_length, &rate, - &channels) < 0) + &channels) != 0) goto out; } padd->sample_rate = rate; @@@ -203,8 -202,8 +202,8 @@@ out } err: assert(ret < 0); - t->error = ret; btr_remove_node(&fn->btrn); + return ret; } /** diff --combined configure.ac index bf83b916,6f0fbc0c..135a0bd9 --- a/configure.ac +++ b/configure.ac @@@ -247,6 -247,18 +247,18 @@@ if test x$ac_cv_have_working_snprintf$a AC_MSG_ERROR([fatal: buggy snprintf() detected]) fi]) AX_FUNC_SNPRINTF() + ################################################################## clock_gettime + clock_gettime_lib= + AC_CHECK_LIB([c], [clock_gettime], [clock_gettime_lib=c], [ + AC_CHECK_LIB([rt], [clock_gettime], [clock_gettime_lib=rt], [], []) + ]) + if test -n "$clock_gettime_lib"; then + AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [ + define to 1 if clock_gettime() is supported]) + fi + if test "$clock_gettime_lib" = "rt"; then + AC_SUBST(clock_gettime_ldflags, -lrt) + fi ########################################################################### osl have_osl=yes OLD_CPPFLAGS="$CPPFLAGS" @@@ -471,17 -483,12 +483,17 @@@ f AC_CHECK_HEADER(curses.h, [], [ have_curses="no" ]) -AC_CHECK_LIB([curses], [initscr], [], [ - have_curses="no" -]) +gui_ldflags="$curses_libs" +AC_CHECK_LIB([ncursesw], [initscr], + [gui_ldflags="$curses_libs -lncursesw"], [ + AC_CHECK_LIB([curses], [initscr], + [gui_ldflags="$curses_libs -lcurses"], + [have_curses="no"] + ) + ] +) if test "$have_curses" = "yes"; then AC_SUBST(curses_cppflags) - AC_DEFINE(HAVE_NCURSES, 1, [define to 1 to turn on curses support]) extras="$extras gui" executables="$executables gui" else @@@ -1248,7 -1255,6 +1260,7 @@@ AC_DEFINE_UNQUOTED(INIT_AUDIOC_ERRLISTS objlist_to_errlist($audioc_errlist_objs), errors used by para_audioc) AC_SUBST(gui_objs, add_dot_o($gui_objs)) +AC_SUBST(gui_ldflags, $gui_ldflags) AC_DEFINE_UNQUOTED(INIT_GUI_ERRLISTS, objlist_to_errlist($gui_errlist_objs), errors used by para_gui) @@@ -1257,6 -1263,8 +1269,6 @@@ AC_SUBST(play_ldflags, $play_ldflags AC_DEFINE_UNQUOTED(INIT_PLAY_ERRLISTS, objlist_to_errlist($play_errlist_objs), errors used by para_play) -AC_MSG_NOTICE(play objs: $play_objs) - enum="$(for i in $filters; do printf "${i}_FILTER, " | tr '[a-z]' '[A-Z]'; done)" AC_DEFINE_UNQUOTED(FILTER_ENUM, $enum NUM_SUPPORTED_FILTERS, enum of supported filters) diff --combined string.c index a416dc80,e5de147c..dfcfa2cd --- a/string.c +++ b/string.c @@@ -6,19 -6,11 +6,18 @@@ /** \file string.c Memory allocation and string handling functions. */ +#define _GNU_SOURCE + - #include /* gettimeofday */ #include #include /* uname() */ + #include #include +#include +#include +#include + #include "para.h" #include "string.h" #include "error.h" @@@ -989,145 -981,3 +988,145 @@@ char *key_value_copy(const char *src, s return NULL; return safe_strdup(src + keylen + 1, len - keylen - 1); } + +static bool utf8_mode(void) +{ + static bool initialized, have_utf8; + + if (!initialized) { + char *info = nl_langinfo(CODESET); + have_utf8 = (info && strcmp(info, "UTF-8") == 0); + initialized = true; + PARA_INFO_LOG("%susing UTF-8 character encoding\n", + have_utf8? "" : "not "); + } + return have_utf8; +} + +/* + * glibc's wcswidth returns -1 if the string contains a tab character, which + * makes the function next to useless. The two functions below are taken from + * mutt. + */ + +#define IsWPrint(wc) (iswprint(wc) || wc >= 0xa0) + +static int mutt_wcwidth(wchar_t wc, size_t pos) +{ + int n; + + if (wc == 0x09) /* tab */ + return (pos | 7) + 1 - pos; + n = wcwidth(wc); + if (IsWPrint(wc) && n > 0) + return n; + if (!(wc & ~0x7f)) + return 2; + if (!(wc & ~0xffff)) + return 6; + return 10; +} + +static size_t mutt_wcswidth(const wchar_t *s, size_t n) +{ + size_t w = 0; + + while (n--) + w += mutt_wcwidth(*s++, w); + return w; +} + +/** + * Skip a given number of cells at the beginning of a string. + * + * \param s The input string. + * \param cells_to_skip Desired number of cells that should be skipped. + * \param bytes_to_skip Result. + * + * This function computes how many input bytes must be skipped to advance a + * string by the given width. If the current character encoding is not UTF-8, + * this is simply the given number of cells, i.e. \a cells_to_skip. Otherwise, + * \a s is treated as a multibyte string and on successful return, \a s + + * bytes_to_skip points to the start of a multibyte string such that the total + * width of the multibyte characters that are skipped by advancing \a s that + * many bytes equals at least \a cells_to_skip. + * + * \return Standard. + */ +int skip_cells(const char *s, size_t cells_to_skip, size_t *bytes_to_skip) +{ + wchar_t wc; + mbstate_t ps; + size_t n, bytes_parsed, cells_skipped; + + *bytes_to_skip = 0; + if (cells_to_skip == 0) + return 0; + if (!utf8_mode()) { + *bytes_to_skip = cells_to_skip; + return 0; + } + bytes_parsed = cells_skipped = 0; + memset(&ps, 0, sizeof(ps)); + n = strlen(s); + while (cells_to_skip > cells_skipped) { + size_t mbret; + + mbret = mbrtowc(&wc, s + bytes_parsed, n - bytes_parsed, &ps); + assert(mbret != 0); + if (mbret == (size_t)-1 || mbret == (size_t)-2) + return -ERRNO_TO_PARA_ERROR(EILSEQ); + bytes_parsed += mbret; + cells_skipped += mutt_wcwidth(wc, cells_skipped); + } + *bytes_to_skip = bytes_parsed; + return 1; +} + +/** + * Compute the width of an UTF-8 string. + * + * \param s The string. + * \param result The width of \a s is returned here. + * + * If not in UTF8-mode. this function is just a wrapper for strlen(3). + * Otherwise \a s is treated as an UTF-8 string and its display width is + * computed. Note that this function may fail if the underlying call to + * mbsrtowcs(3) fails, so the caller must check the return value. + * + * \sa nl_langinfo(3), wcswidth(3). + * + * \return Standard. + */ +__must_check int strwidth(const char *s, size_t *result) +{ + const char *src = s; + mbstate_t state; + static wchar_t *dest; + size_t num_wchars; + + /* + * Never call any log function here. This may result in an endless loop + * as para_gui's para_log() calls this function. + */ + + if (!utf8_mode()) { + *result = strlen(s); + return 0; + } + memset(&state, 0, sizeof(state)); + *result = 0; + num_wchars = mbsrtowcs(NULL, &src, 0, &state); + if (num_wchars == (size_t)-1) + return -ERRNO_TO_PARA_ERROR(errno); + if (num_wchars == 0) + return 0; + dest = para_malloc(num_wchars * sizeof(*dest)); + src = s; + memset(&state, 0, sizeof(state)); + num_wchars = mbsrtowcs(dest, &src, num_wchars, &state); + assert(num_wchars > 0 && num_wchars != (size_t)-1); + *result = mutt_wcswidth(dest, num_wchars); + free(dest); + return 1; +}