summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libglusterfs/src/stack.h18
-rw-r--r--libglusterfs/src/syncop.c31
-rw-r--r--libglusterfs/src/syncop.h9
3 files changed, 37 insertions, 21 deletions
diff --git a/libglusterfs/src/stack.h b/libglusterfs/src/stack.h
index 220eab49d0e..a18ca6deb89 100644
--- a/libglusterfs/src/stack.h
+++ b/libglusterfs/src/stack.h
@@ -177,6 +177,7 @@ STACK_DESTROY (call_stack_t *stack)
}
LOCK_DESTROY (&stack->frames.lock);
+ LOCK_DESTROY (&stack->stack_lock);
while (stack->frames.next) {
FRAME_DESTROY (stack->frames.next);
@@ -187,6 +188,23 @@ STACK_DESTROY (call_stack_t *stack)
mem_put (local);
}
+static inline void
+STACK_RESET (call_stack_t *stack)
+{
+ void *local = NULL;
+
+ if (stack->frames.local) {
+ local = stack->frames.local;
+ stack->frames.local = NULL;
+ }
+
+ while (stack->frames.next) {
+ FRAME_DESTROY (stack->frames.next);
+ }
+
+ if (local)
+ mem_put (local);
+}
#define cbk(x) cbk_##x
diff --git a/libglusterfs/src/syncop.c b/libglusterfs/src/syncop.c
index 4acac5f8fa9..47bb0137da4 100644
--- a/libglusterfs/src/syncop.c
+++ b/libglusterfs/src/syncop.c
@@ -24,22 +24,6 @@
#include "syncop.h"
-call_frame_t *
-syncop_create_frame ()
-{
- struct synctask *task = NULL;
- call_frame_t *frame = NULL;
-
- task = synctask_get ();
-
- if (task) {
- frame = task->frame;
- }
-
- return (call_frame_t *)frame;
-}
-
-
static void
__run (struct synctask *task)
{
@@ -160,6 +144,9 @@ synctask_destroy (struct synctask *task)
if (task->stack)
FREE (task->stack);
+ if (task->opframe)
+ STACK_DESTROY (task->opframe->root);
+
pthread_mutex_destroy (&task->mutex);
pthread_cond_destroy (&task->cond);
@@ -195,18 +182,24 @@ synctask_new (struct syncenv *env, synctask_fn_t fn, synctask_cbk_t cbk,
VALIDATE_OR_GOTO (env, err);
VALIDATE_OR_GOTO (fn, err);
- VALIDATE_OR_GOTO (frame, err);
newtask = CALLOC (1, sizeof (*newtask));
if (!newtask)
return -ENOMEM;
+ newtask->frame = frame;
+ if (!frame) {
+ newtask->opframe = create_frame (this, this->ctx->pool);
+ } else {
+ newtask->opframe = copy_frame (frame);
+ }
+ if (!newtask->opframe)
+ goto err;
newtask->env = env;
newtask->xl = this;
newtask->syncfn = fn;
newtask->synccbk = cbk;
newtask->opaque = opaque;
- newtask->frame = frame;
INIT_LIST_HEAD (&newtask->all_tasks);
@@ -260,6 +253,8 @@ err:
if (newtask) {
if (newtask->stack)
FREE (newtask->stack);
+ if (newtask->opframe)
+ STACK_DESTROY (newtask->opframe->root);
FREE (newtask);
}
return -1;
diff --git a/libglusterfs/src/syncop.h b/libglusterfs/src/syncop.h
index 1bea189a7da..8ec4e9e5868 100644
--- a/libglusterfs/src/syncop.h
+++ b/libglusterfs/src/syncop.h
@@ -56,6 +56,7 @@ struct synctask {
struct syncenv *env;
xlator_t *xl;
call_frame_t *frame;
+ call_frame_t *opframe;
synctask_cbk_t synccbk;
synctask_fn_t syncfn;
synctask_state_t state;
@@ -153,12 +154,14 @@ struct syncargs {
#define SYNCOP(subvol, stb, cbk, op, params ...) do { \
- call_frame_t *frame = NULL; \
+ struct synctask *task = NULL; \
\
- frame = syncop_create_frame (); \
+ task = synctask_get (); \
\
- STACK_WIND_COOKIE (frame, cbk, (void *)stb, subvol, op, params); \
+ STACK_WIND_COOKIE (task->opframe, cbk, (void *)stb, \
+ subvol, op, params); \
__yield (stb); \
+ STACK_RESET (task->opframe->root); \
} while (0)