gam-resource-manager: adjust to updated proxied call callback signature.
[profile/ivi/murphy.git] / src / core / console.h
1 /*
2  * Copyright (c) 2012, Intel Corporation
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *  * Redistributions of source code must retain the above copyright notice,
9  *    this list of conditions and the following disclaimer.
10  *  * Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *  * Neither the name of Intel Corporation nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #ifndef __MURPHY_CONSOLE_H__
31 #define __MURPHY_CONSOLE_H__
32
33 #include <murphy/common/list.h>
34 #include <murphy/common/msg.h>
35 #include <murphy/core/context.h>
36
37 #include <murphy/core/console-command.h>
38
39
40
41 /*
42  * console requests
43  *
44  * Console request correspond to top-down event propagation in the console
45  * communication stack. These requests are made by the core console to the
46  * underlying actual console implementation, typically either as a result
47  * of calls to the console abstraction layer, or in reponse to requests
48  * (ie. input) coming from the actual console implementation.
49  */
50
51 typedef struct {
52     /** Deliver a buffer of data to the given console. */
53     ssize_t (*write)(mrp_console_t *c, void *buf, size_t size);
54     /** Console being closed, close the backend (do not release memory yet). */
55     void (*close)(mrp_console_t *c);
56     /** Console has been destroyed, release resources allocated by backend. */
57     void (*free)(void *data);
58     /** Set the prompt shown to the user at the console. */
59     void (*set_prompt)(mrp_console_t *c, const char *prompt);
60 } mrp_console_req_t;
61
62
63 /*
64  * console events
65  *
66  * Console events correspond to bottom-up event propagation in the console
67  * communication stack. These callbacks are made by the console backend to
68  * the core console to inform about relevant console events, such as new
69  * console input or disconnect by the peer.
70  */
71
72 typedef struct {
73     /** New input available from console. */
74     ssize_t (*input)(mrp_console_t *c, void *buf, size_t size);
75     /** Peer has disconnected from the console. */
76     void (*disconnected)(mrp_console_t *c, int error);
77     /** Generate possible completions for the given input. */
78     ssize_t (*complete)(mrp_console_t *c, void *input, size_t insize,
79                         char **completions, size_t csize);
80 } mrp_console_evt_t;
81
82
83 #define MRP_CONSOLE_PUBLIC_FIELDS                                         \
84     mrp_context_t         *ctx;                                           \
85     mrp_console_req_t      req;                                           \
86     mrp_console_evt_t      evt;                                           \
87     int                  (*check_destroy)(mrp_console_t *c);              \
88     FILE                  *stdout;                                        \
89     FILE                  *stderr;                                        \
90     void                  *backend_data;                                  \
91     int                    busy;                                          \
92     int                    destroyed : 1;                                 \
93     int                    preserve : 1 /* the Kludge of Death, Sir Robin... */
94
95 struct mrp_console_s {
96     MRP_CONSOLE_PUBLIC_FIELDS;
97 };
98
99
100 /**
101  * Macro to mark a console busy while running a block of code.
102  *
103  * The backend needs to make sure the console is not freed while any console
104  * request or event callback function is active. Similarly, the backend needs
105  * to check if the console has been marked for destruction whenever an event
106  * callback returns and trigger destruction if it is necessary and possible
107  * (ie. the above criterium of not being active is fullfilled).
108  *
109  * These are the easiest to accomplish using the provided MRP_CONSOLE_BUSY
110  * macro and the check_destroy callback member provided by mrp_console_t.
111  *
112  *     1) Use the provided MRP_CONSOLE_BUSY macro to enclose al blocks of
113  *        code that invoke event callbacks. Do not do a return directly
114  *        from within the enclosed call blocks, rather just set a flag
115  *        within the block, check it after the block and do the return
116  *        there if necessary.
117  *
118  *     2) Call mrp_console_t->check_destroy after any call to an console
119  *        event callback. check_destroy will check for any pending destroy
120  *        request and perform the actual destruction if it is both necessary
121  *        and possible. If the console has been left intact, check_destroy
122  *        returns FALSE. However, if the console has been destroyed and freed
123  *        it returns TRUE, in which case the caller must not attempt to use
124  *        or dereference the console any more.
125  */
126
127 #ifndef __MRP_CONSOLE_DISABLE_CODE_CHECK__
128 #  define W mrp_log_error
129 #  define __CONSOLE_CHK_BLOCK(...) do {                                   \
130         static int __checked = FALSE, __warned = FALSE;                   \
131                                                                           \
132         if (MRP_UNLIKELY(!__checked)) {                                   \
133             __checked = TRUE;                                             \
134             if (MRP_UNLIKELY(!__warned &&                                 \
135                              strstr(#__VA_ARGS__, "return") != NULL)) {   \
136                 W("********************* WARNING *********************"); \
137                 W("* You seem to directly do a return from a block   *"); \
138                 W("* of code protected by MRP_CONSOLE_BUSY. Are      *"); \
139                 W("* you absolutely sure you know what you are doing *"); \
140                 W("* and that you are also doing it correctly ?      *"); \
141                 W("***************************************************"); \
142                 W("The suspicious code block is located at: ");           \
143                 W("  %s@%s:%d", __FUNCTION__, __FILE__, __LINE__);        \
144                 W("and it looks like this:");                             \
145                 W("---------------------------------------------");       \
146                 W("%s", #__VA_ARGS__);                                    \
147                 W("---------------------------------------------");       \
148                 W("If you understand what MRP_CONSOLE_BUSY does");        \
149                 W("and how, and you are sure about the correctness of");  \
150                 W("your code you can disable this error message by");     \
151                 W("#defining __MRP_CONSOLE_DISABLE_CODE_CHECK__");        \
152                 W("when compiling %s.", __FILE__);                        \
153                 __warned = TRUE;                                          \
154             }                                                             \
155         }                                                                 \
156     } while (0)
157 #else
158 #  define __CONSOLE_CHK_BLOCK(...) do { } while (0)
159 #endif
160
161 #define MRP_CONSOLE_BUSY(c, ...) do {           \
162        __CONSOLE_CHK_BLOCK(__VA_ARGS__);        \
163         (c)->busy++;                            \
164         __VA_ARGS__                             \
165         (c)->busy--;                            \
166     } while (0)
167
168
169 /** Create a new console instance. */
170 mrp_console_t *mrp_create_console(mrp_context_t *ctx, mrp_console_req_t *req,
171                                   void *backend_data);
172
173 /** Close and mark a console for destruction. */
174 void mrp_destroy_console(mrp_console_t *mc);
175
176 /** Send (printf-compatible) formatted output to a console. */
177 void mrp_console_printf(mrp_console_t *mc, const char *fmt, ...);
178
179 /** Send (vprintf-compatible) formatted output to a console. */
180 void mrp_console_vprintf(mrp_console_t *mc, const char *fmt, va_list ap);
181
182 /** Set the prompt of a console. */
183 void mrp_set_console_prompt(mrp_console_t *mc);
184
185 #endif /* __MURPHY_CONSOLE_H__ */