NAME SFI-Functions - SFI Function Reference Document Revised: Wed May 25 23:38:16 2005 SYNOPSIS g_file_test_all(file, test);sfi_file_check(file, mode);sfi_file_crawler_add_search_path(self, pattern_paths, file_pattern);sfi_file_crawler_add_tests(self, tests);sfi_file_crawler_crawl(self);sfi_file_crawler_destroy(self);sfi_file_crawler_list_files(search_path, file_pattern, file_test);sfi_file_crawler_needs_crawl(self);sfi_file_crawler_new();sfi_file_crawler_pop(self);sfi_file_crawler_set_cwd(self, cwd);sfi_guard_deregister(guard);sfi_guard_is_protected(value);sfi_guard_n_snap_values();sfi_guard_protect(guard, nth_hazard, value);sfi_guard_register(n_hazards);sfi_guard_snap_values(n_values, values);sfi_msg_default_handler(msg);sfi_msg_log_elist(log_domain, mtype, lbit1, lbit2, ...);sfi_msg_log_printf(log_domain, level, format, ...);sfi_msg_log_trampoline(log_domain, mtype, lbit1, lbit2, lbitargs, handler, vbitlist);sfi_msg_set_thread_handler(handler);sfi_msg_type_ident(mtype);sfi_msg_type_label(mtype);sfi_msg_type_lookup(ident);sfi_msg_type_register(ident, default_ouput, label, RETURN);sfi_path_get_filename(filename, parentdir);sfi_ring_split(head1, head2);sfi_thread_abort(thread);sfi_thread_aborted();sfi_thread_awake_after(stamp);sfi_thread_emit_wakeups(wakeup_stamp);sfi_thread_get_name(thread);sfi_thread_get_pid(thread);sfi_thread_queue_abort(thread);sfi_thread_run(name, func, user_data);sfi_thread_self();sfi_thread_self_pid();sfi_thread_set_wakeup(wakeup_func, wakeup_data, destroy);sfi_thread_sleep(max_useconds);sfi_thread_wakeup(thread);sfi_time_from_string(time_string);sfi_time_from_string_err(time_string, error_p);sfi_time_from_utc(ustime);sfi_time_system();sfi_time_to_string(ustime);sfi_time_to_utc(ustime); DESCRIPTION g_file_test_all(file, test); const gchar* file; a file to test GFileTest test; bitfield of GFileTest flags This is the AND version of g_file_test(). That is, all file tests specified in the test bits have to succed for this function to return TRUE. This function is implemented via sfi_file_check(), which allowes for more detailed mode tests and is recommended over use of this function. Here is the list of possible GFileTest flags: G_FILE_TEST_IS_REGULAR - test for a recular file G_FILE_TEST_IS_SYMLINK - test for a symlink G_FILE_TEST_IS_DIR - test for a directory G_FILE_TEST_IS_EXECUTABLE - test for an executable G_FILE_TEST_EXISTS - test whether the file exists sfi_file_check(file, mode); const gchar* file; possibly relative filename const gchar* mode; feature string RETURNS: TRUE if file adhears to mode Perform various checks on file and return whether all checks passed. On failure, errno is set appropriately, and FALSE is returned. Available features to be checked for are: e - file must exist r - file must be readable w - file must be writable x - file must be executable f - file must be a regular file d - file must be a directory l - file must be a symbolic link c - file must be a character device b - file must be a block device p - file must be a named pipe s - file must be a socket. sfi_file_crawler_add_search_path(self, pattern_paths, file_pattern); SfiFileCrawler* self; valid SfiFileCrawler const gchar* pattern_paths; colon (semicolon under win32) seperated search path const gchar* file_pattern; wildcard pattern for file names RETURNS: a singly linked list with newly allocated strings This function takes a search path (possibly containing wildcards) and adds them to the file crawlers search list. If file_pattern is non NULL, it is appended to each directory element extracted from pattern_paths, before attempting file system searches. sfi_file_crawler_needs_crawl() may return TRUE after calling this function. sfi_file_crawler_add_tests(self, tests); SfiFileCrawler* self; valid SfiFileCrawler GFileTest tests; GFileTest test flags By default, results returned by self are only tested for existence. If additional file tests have to be met by the results, they can be set by this function. sfi_file_crawler_crawl(self); SfiFileCrawler* self; valid SfiFileCrawler Collect the next file or directory if possible, new results need not arrive after calling this function, and more than one may. This function does nothing if sfi_file_crawler_needs_crawl() returns FALSE. sfi_file_crawler_destroy(self); SfiFileCrawler* self; valid SfiFileCrawler Destroy an existing file crawler and free any resources allocated by it. sfi_file_crawler_list_files(search_path, file_pattern, file_test); const gchar* search_path; colon (semicolon under win32) seperated search path with '?' and '*' wildcards const gchar* file_pattern; wildcard pattern for file names GFileTest file_test; GFileTest file test condition (e.g. G_FILE_TEST_IS_REGULAR) or 0 RETURNS: an SfiRing with newly allocated strings Given a search path with wildcards, list all files matching file_pattern, contained in the directories which the search path matches. Files that do not pass file_test are not listed. sfi_file_crawler_needs_crawl(self); SfiFileCrawler* self; valid SfiFileCrawler RETURNS: TRUE if sfi_file_crawler_crawl() should be called Figure whether collecting all matching files has finished now. If not, sfi_file_crawler_crawl() needs to be called until this function returns FALSE. sfi_file_crawler_new(); Create a new file crawler. A file crawler collects all files matching a given search path and file test. sfi_file_crawler_crawl() needs to be called as long as sfi_file_crawler_needs_crawl() returns TRUE to collect all matching files. sfi_file_crawler_pop(self); SfiFileCrawler* self; valid SfiFileCrawler RETURNS: newly allocated string containig resulting filename Fetch next result if any or NULL. sfi_file_crawler_set_cwd(self, cwd); SfiFileCrawler* self; valid SfiFileCrawler const gchar* cwd; absolute path Set the path to be assumed the current working directory. sfi_guard_deregister(guard); SfiGuard* guard; a valid SfiGuard as returned from sfi_guard_register() Deregister a guard previously registered by a call to sfi_guard_register(). Deregistration is performed in constant time. sfi_guard_is_protected(value); gpointer value; hazard pointer value RETURNS: TRUE if a hazard pointer protecting value has been found Check whether value is protected by a hazard pointer guard. If multiple pointer values are to be checked, use sfi_guard_snap_values() instead, as this function has O(n_hazard_pointers) time complexity. If only one pointer value needs to be looked up though, calling sfi_guard_is_protected() will provide a result faster than calling sfi_guard_snap_values() and looking up the pointer in the filled-in array. Lookup within hazard pointer arrays will always occour in ascending order to allow pointer migration as described in sfi_guard_snap_values() and sfi_guard_register(). sfi_guard_n_snap_values(); RETURNS: an upper bound on the number of registered hazard pointers Retrieve an upper bound on the number of hazard pointer value slots currently required for a successfull call to sfi_guard_snap_values(). Note that a subsequent call to sfi_guard_snap_values() may still fail due to addtional guards being registerted meanwhile. In such a case sfi_guard_n_snap_values() and sfi_guard_snap_values() can simply be called again. sfi_guard_protect(guard, nth_hazard, value); SfiGuard* guard; a valid SfiGuard as returned from sfi_guard_register() guint nth_hazard; index of the hazard pointer to use for protection gpointer value; a hazardous pointer value or NULL to reset protection Protect the node pointed to by value from being destroyed by another thread and against the ABA problem caused by premature reuse. For this to work, threads destroying nodes of the type pointed to by value need to suspend destruction as long as nodes are protected, which can by checked by calls to sfi_guard_is_protected() or by searching the values returned from sfi_guard_snap_values(). Descriptions of safe memory reclamation and ABA problem detection via hazard pointers guards can be found in http://www.research.ibm.com/people/m/michael/podc-2002.pdf , http://www.cs.brown.edu/people/mph/HerlihyLM02/smli_tr-2002-112.pdf , http://research.sun.com/scalable/Papers/CATS2003.pdf and http://www.research.ibm.com/people/m/michael/ieeetpds-2004.pdf . The exact sequence of steps to protect and access a node is as follows: 1) Store the adress of a node to be protected in a hazard pointer 2) Verify that the hazard pointer points to a valid node 3) Dereference the node only as long as it's protected by the hazard pointer. For example: 0: SfiGuard *guard = sfi_guard_register (1); 1: peek_head_label: 2: auto GSList *node = shared_list_head; 3: sfi_guard_protect (guard, 0, node); 4: if (node != shared_list_head) goto peek_head_label; 5: operate_on_protected_node (node); 6: sfi_guard_deregister (guard); sfi_guard_register(n_hazards); guint n_hazards; number of required hazard pointers RETURNS: a valid SfiGuard Retrieve a new guard for node protection of the current thread. The exact mechanism of protection is described in sfi_guard_protect(). Note that sfi_guard_snap_values() will walk the hazard pointer array in ascending order, so that pointers may migrate from array positions with a lower index to positions with a higher index while retaining protection, according to condition C2 as described in http://www.research.ibm.com/people/m/michael/podc-2002.pdf . If an equally or bigger sized hazard pointer array was previously deregistered by this thread, registration takes constant time. sfi_guard_snap_values(n_values, values); guint* n_values; location of n_values variable gpointer* values; value array to fill in RETURNS: TRUE if values provided enough space and is filled Make a snapshot of all non-NULL hazard pointer values. TRUE is returned if the number of non-NULL hazard pointer values didn't exceed the size of the input value array provided by n_values, and all values are returned in the array pointed to by values. The number of values filled in is returned in n_values. FALSE is returned if not enough space was available to return all non-NULL values. sfi_guard_n_snap_values() may be used to retrieve the current upper bound on the number of registered guards. Note that a successive call to sfi_guard_snap_values() with the requested number of value slots supplied may still fail, because additional guards may have been registered meanwhile. In such a case sfi_guard_n_snap_values() and sfi_guard_snap_values() can simply be called again. This funciton will always walk the hazard pointer arrays supplied by sfi_guard_register() in ascending order, to allow pointer migration from lower to higher array indieces while retaining protection. The returned pointer values are unordered, so in order to perform multiple pointer lookups, we recommend sorting the returned array and then doing binary lookups. However if only a single pointer is to be looked up, calling sfi_guard_is_protected() should be considered. sfi_msg_default_handler(msg); const SfiMessage* msg; This is the standard message handler, it produces message in a prominent way on stderr. This function is MT-safe and may be called from any thread. sfi_msg_log_elist(log_domain, mtype, lbit1, lbit2, ...); log_domain; log domain mtype; one of SFI_MSG_ERROR, SFI_MSG_WARNING, SFI_MSG_INFO, SFI_MSG_DIAG lbit1; msg bit lbit2; msg bit ...; list of more msg bits, NULL terminated Log a message through SFIs logging mechanism. The current value of errno is preserved around calls to this function. Usually this function isn't used directly, but sfi_log_msg() is called instead which does not require NULL termination of its argument list and automates the log_domain argument. The log_domain indicates the calling module and relates to G_LOG_DOMAIN as used by g_log(). The msg bit arguments passed in form various parts of the log message, the following macro set is provided to construct the parts from printf-style argument lists: - SFI_MSG_TITLE(): format message title - SFI_MSG_TEXT1(): format primary message (also SFI_MSG_PRIMARY()) - SFI_MSG_TEXT2(): format secondary message, optional (also SFI_MSG_SECONDARY()) - SFI_MSG_TEXT3(): format details of the message, optional (also SFI_MSG_DETAIL()) - SFI_MSG_CHECK(): format configuration check statement to enable/disable log messages of this type. This function is MT-safe and may be called from any thread. sfi_msg_log_printf(log_domain, level, format, ...); log_domain; log domain level; one of SFI_MSG_ERROR, SFI_MSG_WARNING, SFI_MSG_INFO, SFI_MSG_DIAG or SFI_MSG_DEBUG format; printf-like format ...; printf-like arguments Log a message through SFIs logging mechanism. The current value of errno is preserved around calls to this function. Usually this function isn't used directly, but through one of sfi_debug(), sfi_diag(), sfi_info(), sfi_warn() or sfi_error(). The log_domain indicates the calling module and relates to G_LOG_DOMAIN as used by g_log(). This function is MT-safe and may be called from any thread. sfi_msg_log_trampoline(log_domain, mtype, lbit1, lbit2, lbitargs, handler, vbitlist); log_domain; log domain mtype; one of SFI_MSG_ERROR, SFI_MSG_WARNING, SFI_MSG_INFO, SFI_MSG_DIAG lbit1; msg bit lbit2; msg bit lbitargs; va_list list of more msg bits, NULL terminated handler; message handler vbitlist; NULL terminated array of msg bits Construct a log message from the arguments given and let handler process it. This function performs no logging on its own, it is used internally by sfi_log_msg_elist() to collect arguments and construct a message. All logging functionality has to be implemented by handler. Note that all thread-local msg bits are deleted after invokation of this funtcion, so all msg bits created in the current thread are invalid after calling this function. Direct use of this function is not recommended except for implementations of logging mechanisms. This function is MT-safe and may be called from any thread. sfi_msg_set_thread_handler(handler); SfiMsgHandler handler; a valid SfiMsgHandler or NULL Set the handler function for messages logged in the current thread. If NULL is specified as handler, the standard handler will be used. For handler implementations that require an extra data argument, see sfi_thread_set_qdata(). This function is MT-safe and may be called from any thread. sfi_msg_type_ident(mtype); SfiMsgType mtype; Retrive the string identifying the message type type. For invalid (non registered) message types, NULL is returned. This function is MT-safe and may be called from any thread. sfi_msg_type_label(mtype); SfiMsgType mtype; Retrive the label identifying the message type type. Usually, this is a translated version of sfi_msg_type_ident() or NULL if non was registered with the message type. This function is MT-safe and may be called from any thread. sfi_msg_type_lookup(ident); const gchar* ident; message identifier, e.g. "error", "warning", "info", etc... Find the message type correspondign to ident. If no message type was found 0 is returned (note that 0 is also the value of SFI_MSG_NONE). This function is MT-safe and may be called from any thread. sfi_msg_type_register(ident, default_ouput, label, RETURN); ident; message identifier default_ouput; an existing SfiMsgType or FALSE or TRUE label; a translated version of ident RETURN; message type id Register a new message type with identifier ident and user digestible name label. If this function is called multiple times with the same identifier, the type id acquired by the first call will be returned and the other arguments are ignored. As long as the new message type isn't configured individually via sfi_msg_enable(), sfi_msg_allow() or their complements, it shares the configuration of default_ouput. If FALSE or TRUE is passed as default_ouput, this corresponds to SFI_MSG_NONE or SFI_MSG_FATAL respectively which are unconfigrable and always have their output disabled or enabled respectively. As an exception to the rest of the message API, this function may be called before sfi_init(). However note, that MT-safety is only ensured for calls occouring after sfi_init(). This function is MT-safe and may be called from any thread. sfi_path_get_filename(filename, parentdir); const gchar* filename; possibly relative filename const gchar* parentdir; possibly relative parent directory path RETURNS: a newly allocated absolute pathname Construct an absolute filename from filename, using parentdir as parent directory if filename is not absolute. If parentdir is not absolute, it is assumed to be current directory relative. An exception are filenames starting out with '~' and '~USER', these are interpreted to refer to '/home' or '/home/USER' respectively. sfi_ring_split(head1, head2); SfiRing* head1; a non-empty ring SfiRing* head2; a ring node different from head1 contained in head1 RETURNS: head2 for convenience Split a ring into two parts, starting the second ring with head2. head2 must therefore be non-NULL and must be contained in the ring formed by head1. sfi_thread_abort(thread); SfiThread* thread; thread to abort Abort a currently running thread. This function does not return until the thread in question terminated execution. Note that the thread handle gets invalidated with invocation of sfi_thread_abort() or sfi_thread_queue_abort(). sfi_thread_aborted(); RETURNS: TRUE if the thread should abort execution Find out if the currently running thread should be aborted (the thread is supposed to return from its main thread function). This function or alternatively sfi_thread_sleep() should be called periodically, to react to thread abortion requests and to update internal accounting information. sfi_thread_awake_after(stamp); guint64 stamp; stamp to trigger wakeup Wake the current thread up at the next invocation of sfi_thread_emit_wakeups() with a wakup_stamp greater than stamp. sfi_thread_emit_wakeups(wakeup_stamp); guint64 wakeup_stamp; wakeup stamp to trigger wakeups Wake all currently sleeping threads up which queued a wakeup through sfi_thread_awake_after() with a stamp smaller than wakeup_stamp. sfi_thread_get_name(thread); SfiThread* thread; a valid SfiThread handle RETURNS: thread name Return the name of thread as specified upon invokation of sfi_thread_run() or assigned by sfi_thread_set_name(). sfi_thread_get_pid(thread); SfiThread* thread; a valid SfiThread handle RETURNS: thread id Return the specific id for thread. This function is highly system dependant. The thread id may deviate from the overall process id or not. On linux, threads have their own id, allthough since kernel 2.6, they share the same process id. sfi_thread_queue_abort(thread); SfiThread* thread; thread to abort Same as sfi_thread_abort(), but returns as soon as possible, even if thread hasn't stopped execution yet. Note that the thread handle gets invalidated with invocation of sfi_thread_abort() or sfi_thread_queue_abort(). sfi_thread_run(name, func, user_data); const gchar* name; thread name SfiThreadFunc func; function to execute in new thread gpointer user_data; user data to pass into func RETURNS: new thread handle or NULL in case of error Create a new thread running func. sfi_thread_self(); RETURNS: thread handle Return the thread handle of the currently running thread. sfi_thread_self_pid(); RETURNS: thread id Return the thread specific id. This function is highly system dependant. The thread id may deviate from the overall process id or not. On linux, threads have their own id, allthough since kernel 2.6, they share the same process id. sfi_thread_set_wakeup(wakeup_func, wakeup_data, destroy); SfiThreadWakeup wakeup_func; wakeup function to be called by sfi_thread_wakeup() gpointer wakeup_data; data passed into wakeup_func() GDestroyNotify destroy; destroy handler for wakeup_data Set the wakeup function for the current thread. This enables the thread to be woken up through sfi_thread_wakeup() even if not sleeping in sfi_thread_sleep(). The wakeup function must be thread-safe, so it may be called from any thread, and it should be fast, because the global thread system lock is held during its invokation. Per thread, the wakeup function may be set only once. sfi_thread_sleep(max_useconds); glong max_useconds; maximum amount of micro seconds to sleep (-1 for infinite time) RETURNS: TRUE while the thread should continue execution Sleep for the amount of time given. This function may get interrupted by wakeup requests from sfi_thread_wakeup(), abort requests from sfi_thread_queue_abort() or other means. It returns whether the thread is supposed to continue execution after waking up. This function or alternatively sfi_thread_aborted() should be called periodically, to react to thread abortion requests and to update internal accounting information. sfi_thread_wakeup(thread); SfiThread* thread; thread to wake up Wake up a currently sleeping thread. In practice, this function simply causes the next call to sfi_thread_sleep() within thread to last for 0 seconds. sfi_time_from_string(time_string); const gchar* time_string; string containing human readable date and time RETURNS: parsed time in micro seconds or 0 on error Simple variant of sfi_time_from_string_err(). sfi_time_from_string_err(time_string, error_p); const gchar* time_string; string containing human readable date and time gchar** error_p; location for newly allocated string containing conversion errors RETURNS: parsed time in micro seconds, may be 0 on error Parse date and time from a string of characters and indicate possible errors. Several attempts are made to reconstruct a valid date and time despite possible errors. However, if all attempts fail, the returned time is 0. The time returned is UTC, refer to sfi_time_from_utc() in order to retrieve the local standard time. sfi_time_from_utc(ustime); SfiTime ustime; UTC relative time in micro seconds RETURNS: local standard time in micro seconds Convert the Coordinated Universal Time (UTC) ustime into local standard time. This function is MT-safe and may be called from any thread. sfi_time_system(); RETURNS: Current system time in micro seconds Get the current system time in micro seconds. Subsequent calls to this function do not necessarily return greater values. In fact, a second call may return a value smaller than the first call under certain system conditions. The time returned is UTC, refer to sfi_time_from_utc() in order to retrieve the local standard time. This function is MT-safe and may be called from any thread. sfi_time_to_string(ustime); SfiTime ustime; time in micro seconds RETURNS: newly allocated string Retrieve the time ustime in human readable form. The returned time string describes UTC time and thus contains no time zone or UTC offset information. sfi_time_to_utc(ustime); SfiTime ustime; local standard time in micro seconds RETURNS: UTC relative time in micro seconds Convert the local standard time ustime into Coordinated Universal Time (UTC). This function is MT-safe and may be called from any thread. Document Revised: Wed May 25 23:38:16 2005