+
+
Miscellaneous Coding Conventions
+
+
+
C Standard
+ Code in
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.
+
+ For example static inline> and
+ _StaticAssert() 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.
+
+
+
+
+
Function-Like Macros and Inline Functions
+ Both, macros with arguments and 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
+#define Max(x, y) ((x) > (y) ? (x) : (y))
+
+ 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.
+
+ 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.
+#ifndef FRONTEND
+static inline MemoryContext
+MemoryContextSwitchTo(MemoryContext context)
+{
+ MemoryContext old = CurrentMemoryContext;
+
+ CurrentMemoryContext = context;
+ return old;
+}
+#endif /* FRONTEND */
+
+ In this example CurrentMemoryContext>, which is only
+ available in the backend, is referenced and the function thus
+ hidden with a #ifndef FRONTEND. This rule
+ exists because some compilers emit references to symbols
+ contained in inline functions even if the function is not used.
+
+
+
+
+
Writing Signal Handlers
+ 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.
+
+ Barring special arrangements code in signal handlers may only
+ call async-signal safe functions (as defined in posix) and access
+ variables of type volatile sig_atomic_t. A few
+ functions in postgres are also deemed signal safe, importantly
+ SetLatch().
+
+ 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:
+static void
+handle_sighup(SIGNAL_ARGS)
+{
+ int save_errno = errno;
+
+ got_SIGHUP = true;
+ SetLatch(MyLatch);
+
+ errno = save_errno;
+}
+
+ errno> is safed and restored because
+ SetLatch()> might change it. If that were not done
+ interrupted code that's currently inspecting errno might see the wrong
+ value.
+
+
+
+