</sect1>
+ <sect1 id="source-conventions">
+ <title>Miscellaneous Coding Conventions</title>
+
+ <simplesect>
+ <title>C Standard</title>
+ <para>
+ Code in <productname>PostgreSQL</> should only rely on language
+ features available in the C89 standard. That means a conforming
+ C89 compiler has to be able to compile postgres, at least aside
+ from a few platform dependant pieces. Features from later
+ revision of the C standard or compiler specific features can be
+ used, if a fallback is provided.
+ </para>
+ <para>
+ For example <literal>static inline</> and
+ <literal>_StaticAssert()</literal> are currently used, even
+ though they are from newer revisions of the C standard. If not
+ available we respectively fall back to defining the functions
+ without inline, and to using a C89 compatible replacement that
+ performs the same checks, but emits rather cryptic messages.
+ </para>
+ </simplesect>
+
+ <simplesect>
+ <title>Function-Like Macros and Inline Functions</title>
+ <para>
+ Both, macros with arguments and <literal>static inline</>
+ functions, may be used. The latter are preferable if there are
+ multiple-evaluation hazards when written as a macro, as e.g. the
+ case with
+<programlisting>
+#define Max(x, y) ((x) > (y) ? (x) : (y))
+</programlisting>
+ or when the macro would be very long. In other cases it's only
+ possible to use macros, or at least easier. For example because
+ expressions of various types need to be passed to the macro.
+ </para>
+ <para>
+ When the definition an inline function references symbols
+ (i.e. variables, functions) that are only available as part of the
+ backend, the function may not be visible when included from frontend
+ code.
+<programlisting>
+#ifndef FRONTEND
+static inline MemoryContext
+MemoryContextSwitchTo(MemoryContext context)
+{
+ MemoryContext old = CurrentMemoryContext;
+
+ CurrentMemoryContext = context;
+ return old;
+}
+#endif /* FRONTEND */
+</programlisting>
+ In this example <literal>CurrentMemoryContext</>, which is only
+ available in the backend, is referenced and the function thus
+ hidden with a <literal>#ifndef FRONTEND</literal>. This rule
+ exists because some compilers emit references to symbols
+ contained in inline functions even if the function is not used.
+ </para>
+ </simplesect>
+
+ <simplesect>
+ <title>Writing Signal Handlers</title>
+ <para>
+ To be suitable to run inside a signal handler code has to be
+ written very carefully. The fundamental problem is that, unless
+ blocked, a signal handler can interrupt code at any time. If code
+ inside the signal handler uses the same state as code outside
+ chaos may ensue. As an example consider what happens if a signal
+ handler tries to acquire a lock that's already held in the
+ interrupted code.
+ </para>
+ <para>
+ Barring special arrangements code in signal handlers may only
+ call async-signal safe functions (as defined in posix) and access
+ variables of type <literal>volatile sig_atomic_t</literal>. A few
+ functions in postgres are also deemed signal safe, importantly
+ <literal>SetLatch()</literal>.
+ </para>
+ <para>
+ In most cases signal handlers should do nothing more than note
+ that a signal has arrived, and wake up code running outside of
+ the handler using a latch. An example of such a handler is the
+ following:
+<programlisting>
+static void
+handle_sighup(SIGNAL_ARGS)
+{
+ int save_errno = errno;
+
+ got_SIGHUP = true;
+ SetLatch(MyLatch);
+
+ errno = save_errno;
+}
+</programlisting>
+ <literal>errno</> is safed and restored because
+ <literal>SetLatch()</> might change it. If that were not done
+ interrupted code that's currently inspecting errno might see the wrong
+ value.
+ </para>
+ </simplesect>
+
+ </sect1>
</chapter>