path: root/libglusterfs/src/globals.h
diff options
authorPavan Sondur <>2010-07-25 18:13:08 +0000
committerAnand V. Avati <>2010-07-28 23:58:13 -0700
commitfac3ff8bfb3958a3bdc34dc9bff7cb281597e40f (patch)
treeed16cfdbdb386ef81f957533f9d563076da953c7 /libglusterfs/src/globals.h
parentcadd1256355f4e1a5bd43c3a71dbd6cb97dff66d (diff)
syncop: initial implementation
Resending Avati's syncop patch with a few bug fixes. (please do not skip the IMPORTANT NOTES section) * Framework for SYNChronous OPerations -------------------------------------- This patch provides a framework for performing synchronous operations over the underlying actual asynchronous GlusterFS FOPS. * Use cases ----------- 1. Convenient implementation of crawler thread in replicate/pump 2. Convenient implementation of high level control flow in DVM * Background ------------ All (almost) threads in GlusterFS are hosts for executing aysnchronous file operations using the STACK_WIND and STACK_UNWIND primitives - as calls and callbacks. While the STACK_WIND and STACK_UNWIND macros provide high control for efficiently implementing file operations in a clustered/parallel environment, there are tasks where the nature of the task itself is sequential and the execution performance of the task is not critical. In these cases the complexity to implement the task with STACK_WIND/STACK_UNWIND based operations as calls and callbacks is an overkill. * Introduction --------------- syncop: are wrappers around the STACK_WIND/STACK_UNWIND based asynchronous fops. synctask: a sequential task (a C function) which uses syncops. syncenv: an environement to schedule and execute synctasks. The synchronicity is implemented via ucontext.h based continuations. Execution of synchronous tasks is possible only in a synchronous environment. Therefore, the first step is to create such an environment - struct syncenv *env = syncenv_new (0); This creates a synchronous environment, with a thread (scheduler) to host the synchronous tasks. Creation of this environment is generally to be done at the time of process initialization. Next is to spawn a synchronous task in this environment - int slow_self_heal (void *data); int completion_func (int ret, void *data); ret = synctask_new (env, slow_self_heal, completion_func, data); Here slow_self_heal is a task which is implemented using synchronous operations. When slow_self_heal() completes, completion_func() is called with the first parameter as the return value of slow_self_heal(). Both these functions get the @data argument as the same value passed to synctask_new(). int slow_self_heal (void *data) { xlator_t *child = FIRST_CHILD (THIS); fd_t *dir = NULL; ... dir = syncop_opendir (child, loc); entry = syncop_readdir (dir); ... return ret; } * IMPORTANT NOTES ----------------- - calling syncops in code executing outside the synchronous environment will very likely cause and undesired blocking of the executing thread leading to deadlocks!! The synchronous environment is a special thread where such sleeps are safe, and these sleeps result in the scheduler to 'swap in' other synctasks. - syncops can put the task to sleep. DO NOT issue syncops while holding mutexes. This is very similar to the blunder of holding a mutex and doing STACK_WIND. - It works best when synctasks use only syncops. If a call_frame is created and STACK_WIND'ed, the callback would very likely happen in a thread outside the synchronous enviroment, at an undefined time - as expected. So note that the synchronous environment does not tame the notorious behaviour of STACK_WIND. Signed-off-by: Anand V. Avati <> Signed-off-by: Anand V. Avati <> BUG: 971 (dynamic volume management) URL:
Diffstat (limited to 'libglusterfs/src/globals.h')
1 files changed, 5 insertions, 0 deletions
diff --git a/libglusterfs/src/globals.h b/libglusterfs/src/globals.h
index e09c69511..bdd9e8910 100644
--- a/libglusterfs/src/globals.h
+++ b/libglusterfs/src/globals.h
@@ -42,10 +42,15 @@ xlator_t **__glusterfs_this_location ();
xlator_t *glusterfs_this_get ();
int glusterfs_this_set (xlator_t *);
+/* central log */
void glusterfs_central_log_flag_set ();
long glusterfs_central_log_flag_get ();
void glusterfs_central_log_flag_unset ();
+/* task */
+void *synctask_get ();
+int synctask_set (void *);
/* init */
int glusterfs_globals_init (void);