I'd have to look into it to be sure, but I think the scenario you describe may 
well be possible.

However... couldn't you just put the creation/registration of the PendingFlow 
*before* sending either of the commands?

-- Murphy

On Sep 12, 2011, at 7:10 AM, Zoltán Lajos Kis wrote:

> Hi,
>  
> In my C++ NOX (Zaku) app I would like to make sure that a flow is installed 
> on the switch. Having no better solution, I send a barrier request right 
> after the flow_mod, and then wait for either an error, or a barrier reply.
> For this I register the flow_mod's and barrier's xids, and then compare 
> incoming events against those. See the pseudoish code below for an example.
>  
> Could someone familiar with the cooperative thread implementation in NOX tell 
> me, whether it is possible that a blocking send_openflow_command() result in 
> the current thread actually blocking and yielding to another one?
> Particularly in this code, can it happen that sending the flow_mod completes, 
> but then the second call to send blocks, yielding to another thread. Then on 
> this other thread the incoming error message is received and dispatched to 
> the handler method? Resulting in the error being discarded as at that time 
> the PendingFlow was not even registered…
>  
> And if so, is there a way to temporarily disable this yielding, or do I 
> better start making the code more complex?
>  
> Thank you,
> Zoltan.
>  
>  
> ------------------------------
>  
>  
> struct PendingFlow {
>   uint32_t modXid;
>   uint32_t barrierXid;
>   ...
> }
>  
> class Example {
>  
>   PendingFlow *pendingFlow;
>   ...
>  
>   void
>   Example::install_flow(ofp_flow_mod *mod) {
>      ofp_header *barrier = make_barrier();
>  
>     mod->header->xid = generate_xid();
>     barrier->xid = generate_xid();
>  
>     send_openflow_command(pi.datapath_id, &mod->header, true);
>     send_openflow_command(pi.datapath_id, barrier, true);
>  
>     pendingFlow = new PendingFlow(mod->header->xid, barrier->xid);
>     ...
>   }
>  
>  
>   Disposition
>   Example::handleError(const Event &e) {
>     const Error_event& err = assert_cast<const Error_event&>(e);
>  
>     if (pendingFlow != NULL && pendingFlow.modXid == getErrorXid(err)) {
>       delete pendingFlow; pendingFlow = NULL;
>       // Process error
>     }
>    …
>     return CONTINUE;
>   }
>  
>   Disposition
>   Example::handleBarrier(const Event &e) {
>     const Barrier_reply_event& barrier = assert_cast<const 
> Barrier_reply_event>(e);
>  
>     if (pendingFlow != NULL && pendingFlow.barrierXid == 
> getBarrierXid(barrier)) {
>       delete pendingFlow; pendingFlow = NULL;
>       // Process completion
>     }
>     ..
>     return CONTINUE;
>   }
>  
>   …
> }
>  
> _______________________________________________
> nox-dev mailing list
> nox-dev@noxrepo.org
> http://noxrepo.org/mailman/listinfo/nox-dev

_______________________________________________
nox-dev mailing list
nox-dev@noxrepo.org
http://noxrepo.org/mailman/listinfo/nox-dev

Reply via email to