Consolidate EOF error codes. Currently we have ~15 error codes which indicate an EOF condition. One should suffice, so drop all codes except the generic E_EOF and use that everywhere.
sched: Improve error diagnostics. Currently the error code of the negative return value from ->post_monitor() is not logged anywhere under normal conditions. Instead we log "[dead]" in unlink_and_free_task(). Replace this by a more meaningful message in task_reap().
Merge topic branch t/overflow into master This series implements a new memory allocation API which checks for overflows. The first part of the series just renames the main allocation functions. Later patches in the series implement allocators which take two size_t arguments (like calloc(3)) and check whether the multiplication overflows by employing the __builtin_mul_overflow() primitive supported by gcc and clang. This requires us to bump the lowest supported gcc and clang version. * refs/heads/t/overflow: build: Compile with -ftrapv. string: Introduce arr_zalloc(). string: Introduce arr_alloc(). string: Introduce arr_realloc() and check for integer overflow. string: Rename para_calloc() -> zalloc(). string: Rename para_malloc() -> alloc(). string: Overhaul para_strdup().
Switch from select(2) to poll(2). The select(2) API is kind of obsolete because it does not work for file descriptors greater or equal than 1024, The general advice is to switch to poll(2), which offers equivalent functionality and does not suffer from this restriction. This patch implements this switch. The fd sets of select(2) have one nice feature: One can determine in O(1) time whether the bit for a given fd is turned on in an fd set. For poll(2), the monitored file descriptors are organized in an array of struct pollfd. Without information about the given fd's index in the pollfd array, one can only perform a linear search which requires O(n) time, with n being the number of fds being watched. Since this would have to be done for each fd, the running time becomes quadratic in the number of monitored fds, which is bad. Keeping the pollfd array sorted would reduce that to n * log(n) at the cost of additional work at insert time. This patch implements a different approach. The scheduler now maintains an additional array of unsigned integers which map fds to indices into the pollfd array. This new index array is transparent to the individual tasks, which still simply pass one or more fds from their ->pre_monitor() method to the scheduler. The length of the index array equals the highest fd given. This might become prohibitive in theory, but should not be an issue for the time being. Care needs to be taken in order to deal with callers which ask for the readiness of an fd without having called sched_monitor_readfd() or sched_monitor_writefd() in the ->pre_monitor() step. Before the patch, thanks to the FD_ZERO() call at the beginning of each iteration of the scheduler's main loop, both sched_read_ok() and sched_write_ok() returned false for fds which were not asked to be watched. We need to keep it this way for a seamless transition. We achieve this by replacing the FD_ZERO() call by a memset(3) call which fills the index array with 0xff bytes. Both sched_read_ok() and sched_write_ok() call the new get_revents() helper, where we check the fd argument against the allocation sizes of the two arrays. If either function is called with an fd that was not asked to be monitored in the ->pre_monitor() step, the checks notice that the index of this fd, 0xffffffff, is larger than the highest open fd and we return "not ready for I/O". Another issue is the case where the same file descriptor is submitted twice in ->pre_monitor() to check for readiness with respect to both reading and writing. The code in client_comon.c currently does that. To keep it working, the scheduler needs to detect this case and re-use the existing slot in both arrays.
Rename ->{pre,post}_select methods to ->{pre,post}_monitor. The word "monitor" is neutral and continues to be correct after the switch from select(2) to poll(2). Pure rename, nothing to see here.
Hide implementation of para_fd_set(). This preparatory patch for replacing select() renames para_fd_set() to sched_fd_set(), moves it to sched.c and makes it static. All users are modified to call either of the two new public functions sched_monitor_{read,write}fd() which take a pointer to struct sched rather than an fd set pointer.
sched: Use integer value for select timeout. This modifies the public struct sched so that users pass in the default timeout as an integer value in milliseconds rather than a struct timeval. This simplifies the code a little and eases the transition from select(2) to poll(2) because poll(2) also takes a plain integer for the timeout. Since para_select() of fd.c now calls ms2tv() to convert the timeout back to a struct timeval, all executables which link with fd.o must also link with time.o. This was not the case for para_mixer and para_audioc, so configure.ac needs to be adjusted accordingly.
string: Rename para_malloc() -> alloc(). Just because it's shorter and matches the naming of the new allocators we are about to introduce. The bulk of this patch was created with sed -i 's/para_malloc/alloc/g' *.c *.h yy/mp.y
list.h: Convert INIT_LIST_HEAD macro to inline function. Inline functions are easier to read and write, and we get type safety.
Fix bad grammar "allows <infinitive>". In standard English, the verb "allows" can never take an infinitive as its direct object. This patch corrects these mistakes.
Shorten copyright notice. The GPLv2 line does not add any additional information, so drop it. This leaves a single line of legalese text for most files, which is about the amount of screen real estate it deserves. This patch was created with the following script (plus some manual fixups): awk '{ if (NR <= 5) { gs = gensub(/.*Copyright.* ([0-9]+).*Andre Noll.*/, "\\1", "g") if (gs != $0) year = gs next } if (NR == 6 && year != "") printf("/* Copyright (C) %s Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */\n", year) print }'
doxygen: Add \ref to references. This way doxygen issues a warning if the file/function/structure no longer exists and a stale reference remains.
sched: Log task termination status. This is generally useful information, so let's include it in the log message.
Update year in copyright headers. Done with files=$(git grep -l 'Copyright (C) [0-9]\{4\}\(-2014\)* Andre Noll') sed --in-place= -e 's/Copyright (C) \([0-9]\{4\}\)-2014 Andre Noll/Copyright (C) \1 Andre Noll/1' $files In previous years we ran a similar script to set the second year in the range to the current year. This is kind of silly, so let's get rid of this useless information. This commit replaces "Copyright (C) A-B" by "Copyright (C) A" in all file headers, i.e. only the first year (A) is left in. Accurate information including time stamps for each change can be obtained from the git history.
sched.c: Remove unused timeout_is_zero(). Found by cppcheck.
Remove unnecessary system header includes. All these headers get included from para.h.
doc: Change email address to maan@tuebingen.mpg.de The mail server on systemlinux.org was down for more than a week lately, so let's use an alternative official address. This commit changes all maan@systemlinux.org addresses to maan@tuebingen.mpg.de. Most .c and .h files contain the email address in the copyright header, so they must all be patched. Three other files contain the address for a different reason: * README lists email and git, gitweb and home page URLs * configure.ac needs it for configure -h * version.c contains it for the -V option of all commands
sched: Mark global now pointer as const. The timeval structure pointed to by the public now pointer should not be modified outside sched.c. Fortunately play.c is the only place which violates this rule. This patch fixes up play.c and marks the pointer as const.
sched: Directly pass context pointer to pre/post_select(). The patch is large, but it's fairly straight forward: Instead of a task pointer all ->pre_select() and ->post_select() methods now receive the context pointer that was passed to the scheduler when the task was registered. This allows to kill the public task_context(). Two pre_select/post_select functions are not directly called by the scheduler: session_post_select(), generic_recv_pre_select(). These are changed to receive a proper struct rather than a void pointer. Note that generic_filter_pre_select() is not changed in this manner because some filters do not provide a pre_select wrapper but set task->pre_select to generic_filter_pre_select().
sched: kill task->dead. The three possible states of a task are determined by the ->status and ->dead fields of struct task: status >= 0, !dead: running status >= 0, dead: dead (about to be removed from the task list) status < 0: zombie (dead, but not yet reaped, -status is an error code) This commit encodes the first two states as two non-negative numbers, so that the three states become status == TS_RUNNING: running status == TS_DEAD: dead status < 0: zombie This allows to remove ->dead which improves readability somewhat.