The strategy is to defer yield'ing of
the task till a mgmt operation is sent to all the peers.
If I understand it right, the following theorem is true, - A function which begins execution in a synctask (ie. thread from syncenv's thread pool), would always resume execution (ie, wake) in the same thread (viz. part of syncenv's thread pool). If the above theorem is correct, then all syncops performed by mgmt operation handlers are guaranteed to be called from a syncenv. The synctask is spawned at rpcsvc layer for all glusterd mgmt operations programs. Following is an example code snippet. <code> gd_lock_op_phase (struct list_head *peers, char **op_errstr, int npeers) { .... list_for_each_entry (peerinfo, peers, op_peers_list) { gd_syncop_mgmt_lock (peerinfo->rpc, aggr, index, MY_UUID, peer_uuid); index++; } synctask_yield (aggr->task); //note: block in the above line until all the cbks return - call_cnt mechanism .... } #define GD_SYNCOP(rpc, stb, cbk, req, prog, procnum, xdrproc) do { \ int ret = 0; \ struct synctask *task = NULL; \ \ task = synctask_get (); \ stb->task = task; \ ret = gd_syncop_submit_request (rpc, req, stb, \ prog, procnum, cbk, \ (xdrproc_t)xdrproc); \ // note: yield here has been removed } while (0) </code> Let me know if we can come up with a generic framework for what I am trying to do here. thanks, krish On 02/14/2013 05:23 AM, Anand Avati wrote: So you are not using the SYNCOP() macro, right? Can you show a code snippet of how you are trying to fan-out and yield? We could probably come up with a generic framework for such fan-out->yield->wake pattern. |