How to porperly exit program when receive cmd from ubs?

Hi All,

I'm trying to use ubus to deliver cmd to my program and ask program to exit.
Please check following code.

void videod_ubus::ubus_reply_okay(struct ubus_request_data *req)
  {
      blob_buf_init(&blob, 0);                                                                                                               
      blobmsg_add_string(&blob, "reply", "okay");                                                                                           
      ubus_send_reply(ctx, req, blob.head);
      ubus_complete_deferred_request(ctx, req, 0);
  }
                                                                                                                             
  int videod_exit(struct ubus_context *ctx, struct ubus_object *obj,
          struct ubus_request_data *req, const char *method,
          struct blob_attr *msg)
  {                                                                                                                                         
      if (videod_instance) {
          videod_instance->ubus_reply_okay(req);
          videod_instance->set_exit(true);
          uloop_end();
      }                                                                                                                                     
      return 0;
  }

When program receive "exit" method, "videod_exit" will be called. At that moment, I try to reply "okay" and cancel uloop to exit program.
But sometimes, the client(ubus call vidoed exit) will be blocked for timeout.
What should I do to fix timeout issue? Thanks.

Try delaying the shutdown by 100ms or so. When receiving the exit command, set a global variable which causes all other ubus methods to reply with an error (in case other requests are received after the exit request) but before the service shutdown, then schedule an uloop timeout which invokes a callback to shutdown the program a few milliseconds later.

Hi Jow,

Thanks. It works.
I feel a little confusing about 'ubus_complete_deferred_request', does it notify receiver to end connection? If yes, why we still need to usleep a little time to get anything done? Thanks.

Yes, the ubus_complete_deferred_request() should notify the receiver and cleanly complete the call. I do not know why you're running into a timeout. I suspect the status reply message is never sent before the socket is shut down.

I suggest running your videod process under strace to see what is happening exactly in the timeout case.

1 Like

Hi Jow,

Thanks. I will check it later.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.