Mercurial > urweb
comparison doc/manual.tex @ 1329:9be9da2df74b
Clarifying some C FFI details in manual
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Sat, 11 Dec 2010 11:00:05 -0500 |
parents | c5799b1e4c58 |
children | a6427d1eda6f |
comparison
equal
deleted
inserted
replaced
1328:c5799b1e4c58 | 1329:9be9da2df74b |
---|---|
2122 \item \begin{verbatim} | 2122 \item \begin{verbatim} |
2123 void uw_error(uw_context, failure_kind, const char *fmt, ...); | 2123 void uw_error(uw_context, failure_kind, const char *fmt, ...); |
2124 \end{verbatim} | 2124 \end{verbatim} |
2125 Abort the current request processing, giving a \texttt{printf}-style format string and arguments for generating an error message. The \texttt{failure\_kind} argument can be \texttt{FATAL}, to abort the whole execution; \texttt{BOUNDED\_RETRY}, to try processing the request again from the beginning, but failing if this happens too many times; or \texttt{UNLIMITED\_RETRY}, to repeat processing, with no cap on how many times this can recur. | 2125 Abort the current request processing, giving a \texttt{printf}-style format string and arguments for generating an error message. The \texttt{failure\_kind} argument can be \texttt{FATAL}, to abort the whole execution; \texttt{BOUNDED\_RETRY}, to try processing the request again from the beginning, but failing if this happens too many times; or \texttt{UNLIMITED\_RETRY}, to repeat processing, with no cap on how many times this can recur. |
2126 | 2126 |
2127 All pointers to the context-local heap (see description below of \texttt{uw\_malloc()}) become invalid at the start and end of any execution of a main entry point function of an application. For example, if the request handler is restarted because of a \texttt{uw\_error()} call with \texttt{BOUNDED\_RETRY} or for any other reason, it is unsafe to access any local heap pointers that may have been stashed somewhere beforehand. | |
2128 | |
2127 \item \begin{verbatim} | 2129 \item \begin{verbatim} |
2128 void uw_push_cleanup(uw_context, void (*func)(void *), void *arg); | 2130 void uw_push_cleanup(uw_context, void (*func)(void *), void *arg); |
2129 void uw_pop_cleanup(uw_context); | 2131 void uw_pop_cleanup(uw_context); |
2130 \end{verbatim} | 2132 \end{verbatim} |
2131 Manipulate a stack of actions that should be taken if any kind of error condition arises. Calling the ``pop'' function both removes an action from the stack and executes it. | 2133 Manipulate a stack of actions that should be taken if any kind of error condition arises. Calling the ``pop'' function both removes an action from the stack and executes it. It is a bug to let a page request handler finish successfully with unpopped cleanup actions. |
2134 | |
2135 Pending cleanup actions aren't intended to have any complex relationship amongst themselves, so, upon request handler abort, pending actions are executed in first-in-first-out order. | |
2132 | 2136 |
2133 \item \begin{verbatim} | 2137 \item \begin{verbatim} |
2134 void *uw_malloc(uw_context, size_t); | 2138 void *uw_malloc(uw_context, size_t); |
2135 \end{verbatim} | 2139 \end{verbatim} |
2136 A version of \texttt{malloc()} that allocates memory inside a context's heap, which is managed with region allocation. Thus, there is no \texttt{uw\_free()}, but you need to be careful not to keep ad-hoc C pointers to this area of memory. | 2140 A version of \texttt{malloc()} that allocates memory inside a context's heap, which is managed with region allocation. Thus, there is no \texttt{uw\_free()}, but you need to be careful not to keep ad-hoc C pointers to this area of memory. In general, \texttt{uw\_malloc()}ed memory should only be used in ways compatible with the computation model of pure Ur. This means it is fine to allocate and return a value that could just as well have been built with core Ur code. In contrast, it is almost never safe to store \texttt{uw\_malloc()}ed pointers in global variables, including when the storage happens implicitly by registering a callback that would take the pointer as an argument. |
2137 | 2141 |
2138 For performance and correctness reasons, it is usually preferable to use \texttt{uw\_malloc()} instead of \texttt{malloc()}. The former manipulates a local heap that can be kept allocated across page requests, while the latter uses global data structures that may face contention during concurrent execution. | 2142 For performance and correctness reasons, it is usually preferable to use \texttt{uw\_malloc()} instead of \texttt{malloc()}. The former manipulates a local heap that can be kept allocated across page requests, while the latter uses global data structures that may face contention during concurrent execution. However, we emphasize again that \texttt{uw\_malloc()} should never be used to implement some logic that couldn't be implemented trivially by a constant-valued expression in Ur. |
2139 | 2143 |
2140 \item \begin{verbatim} | 2144 \item \begin{verbatim} |
2141 typedef void (*uw_callback)(void *); | 2145 typedef void (*uw_callback)(void *); |
2142 typedef void (*uw_callback_with_retry)(void *, int will_retry); | 2146 typedef void (*uw_callback_with_retry)(void *, int will_retry); |
2143 void uw_register_transactional(uw_context, void *data, uw_callback commit, | 2147 void uw_register_transactional(uw_context, void *data, uw_callback commit, |
2145 \end{verbatim} | 2149 \end{verbatim} |
2146 All side effects in Ur/Web programs need to be compatible with transactions, such that any set of actions can be undone at any time. Thus, you should not perform actions with non-local side effects directly; instead, register handlers to be called when the current transaction is committed or rolled back. The arguments here give an arbitary piece of data to be passed to callbacks, a function to call on commit, a function to call on rollback, and a function to call afterward in either case to clean up any allocated resources. A rollback handler may be called after the associated commit handler has already been called, if some later part of the commit process fails. A free handler is told whether the runtime system expects to retry the current page request after rollback finishes. | 2150 All side effects in Ur/Web programs need to be compatible with transactions, such that any set of actions can be undone at any time. Thus, you should not perform actions with non-local side effects directly; instead, register handlers to be called when the current transaction is committed or rolled back. The arguments here give an arbitary piece of data to be passed to callbacks, a function to call on commit, a function to call on rollback, and a function to call afterward in either case to clean up any allocated resources. A rollback handler may be called after the associated commit handler has already been called, if some later part of the commit process fails. A free handler is told whether the runtime system expects to retry the current page request after rollback finishes. |
2147 | 2151 |
2148 Any of the callbacks may be \texttt{NULL}. To accommodate some stubbornly non-transactional real-world actions like sending an e-mail message, Ur/Web treats \texttt{NULL} \texttt{rollback} callbacks specially. When a transaction commits, all \texttt{commit} actions that have non-\texttt{NULL} rollback actions are tried before any \texttt{commit} actions that have \texttt{NULL} rollback actions. Thus, if a single execution uses only one non-transactional action, and if that action never fails partway through its execution while still causing an observable side effect, then Ur/Web can maintain the transactional abstraction. | 2152 Any of the callbacks may be \texttt{NULL}. To accommodate some stubbornly non-transactional real-world actions like sending an e-mail message, Ur/Web treats \texttt{NULL} \texttt{rollback} callbacks specially. When a transaction commits, all \texttt{commit} actions that have non-\texttt{NULL} rollback actions are tried before any \texttt{commit} actions that have \texttt{NULL} rollback actions. Thus, if a single execution uses only one non-transactional action, and if that action never fails partway through its execution while still causing an observable side effect, then Ur/Web can maintain the transactional abstraction. |
2149 | 2153 |
2154 When a request handler ends with multiple pending transactional actions, their handlers are run in a first-in-last-out stack-like order, wherever the order would otherwise be ambiguous. | |
2155 | |
2156 It is not safe for any of these handlers to access a context-local heap through a pointer returned previously by \texttt{uw\_malloc()}, nor should any new calls to that function be made. Think of the context-local heap as meant for use by the Ur/Web code itself, while transactional handlers execute after the Ur/Web code has finished. | |
2157 | |
2150 \item \begin{verbatim} | 2158 \item \begin{verbatim} |
2151 void *uw_get_global(uw_context, char *name); | 2159 void *uw_get_global(uw_context, char *name); |
2152 void uw_set_global(uw_context, char *name, void *data, uw_callback free); | 2160 void uw_set_global(uw_context, char *name, void *data, uw_callback free); |
2153 \end{verbatim} | 2161 \end{verbatim} |
2154 Different FFI-based extensions may want to associate their own pieces of data with contexts. The global interface provides a way of doing that, where each extension must come up with its own unique key. The \texttt{free} argument to \texttt{uw\_set\_global()} explains how to deallocate the saved data. | 2162 Different FFI-based extensions may want to associate their own pieces of data with contexts. The global interface provides a way of doing that, where each extension must come up with its own unique key. The \texttt{free} argument to \texttt{uw\_set\_global()} explains how to deallocate the saved data. It is never safe to store \texttt{uw\_malloc()}ed pointers in global variable slots. |
2155 | 2163 |
2156 \end{itemize} | 2164 \end{itemize} |
2157 | 2165 |
2158 \subsection{Writing JavaScript FFI Code} | 2166 \subsection{Writing JavaScript FFI Code} |
2159 | 2167 |