-/*
- * signals a change of the board
- */
-static void changed(struct board *board, const char *reason)
-{
- struct waiter *waiter, *next;
- struct json_object *description;
-
- /* get the description */
- description = describe(board);
-
- waiter = board->waiters;
- board->waiters = NULL;
- while (waiter != NULL) {
- next = waiter->next;
- afb_req_success(waiter->req, json_object_get(description), reason);
- afb_req_unref(waiter->req);
- free(waiter);
- waiter = next;
+The *tic-tac-toe* example allows two clients or more to share the same board.
+This is implemented by the method **join** that illustrated partly how to
+retrieve arguments.
+
+When two or more clients are sharing a same board, one of them can wait
+until the state of the board changes, but this could also be implemented using
+events because an even is generated each time the board changes.
+
+In this case, the reply to the wait is sent only when the board changes.
+See the diagram below:
+
+ CLIENT A CLIENT B TIC-TAC-TOE
+ | | |
+ +--------------|----------------->| wait . . . . . . . .
+ | | | .
+ : : : .
+ : : : .
+ | | | .
+ | +----------------->| move . . . .
+ | | | V .
+ | |<-----------------+ success of move .
+ | | | .
+ |<-------------|------------------+ success of wait <
+
+Here, this is an invocation of the plugin by an other client that
+unblock the suspended *wait* call.
+Nevertheless in most case this should be a timer, a hardware event, a sync with
+a concurrent process or thread, ...
+
+Common case of an asynchronous implementation.
+
+Here is the listing of the function **wait**:
+
+ static void wait(struct afb_req req)
+ {
+ struct board *board;
+ struct waiter *waiter;
+
+ /* retrieves the context for the session */
+ board = board_of_req(req);
+ INFO(afbitf, "method 'wait' called for boardid %d", board->id);
+
+ /* creates the waiter and enqueues it */
+ waiter = calloc(1, sizeof *waiter);
+ waiter->req = req;
+ waiter->next = board->waiters;
+ afb_req_addref(req);
+ board->waiters = waiter;
+ }
+
+After retrieving the board, the function adds a new waiter to
+waiters list and returns without setting a reply.
+
+Before returning, it increases **req** request's reference count using **afb_req_addref** function.
+
+> When a method returns without setting a reply,
+> it **MUST** increment request's reference count
+> using **afb_req_addref**. If unpredictable behaviour may pop up.
+
+Later, when a board changes, it calls *tic-tac-toe* **changed** function
+with reason of change in parameter.
+
+Here is the full listing of the function **changed**:
+
+ /*
+ * signals a change of the board
+ */
+ static void changed(struct board *board, const char *reason)
+ {
+ struct waiter *waiter, *next;
+ struct json_object *description;
+
+ /* get the description */
+ description = describe(board);
+
+ waiter = board->waiters;
+ board->waiters = NULL;
+ while (waiter != NULL) {
+ next = waiter->next;
+ afb_req_success(waiter->req, json_object_get(description), reason);
+ afb_req_unref(waiter->req);
+ free(waiter);
+ waiter = next;
+ }
+
+ afb_event_sender_push(afb_daemon_get_event_sender(afbitf->daemon), reason, description);