@@ -851,4 +851,109 @@ BETTER: unrecognized node type: 42
851
851
852
852
</sect1>
853
853
854
+ <sect1 id="source-conventions">
855
+ <title>Miscellaneous Coding Conventions</title>
856
+
857
+ <simplesect>
858
+ <title>C Standard</title>
859
+ <para>
860
+ Code in <productname>PostgreSQL</> should only rely on language
861
+ features available in the C89 standard. That means a conforming
862
+ C89 compiler has to be able to compile postgres, at least aside
863
+ from a few platform dependant pieces. Features from later
864
+ revision of the C standard or compiler specific features can be
865
+ used, if a fallback is provided.
866
+ </para>
867
+ <para>
868
+ For example <literal>static inline</> and
869
+ <literal>_StaticAssert()</literal> are currently used, even
870
+ though they are from newer revisions of the C standard. If not
871
+ available we respectively fall back to defining the functions
872
+ without inline, and to using a C89 compatible replacement that
873
+ performs the same checks, but emits rather cryptic messages.
874
+ </para>
875
+ </simplesect>
876
+
877
+ <simplesect>
878
+ <title>Function-Like Macros and Inline Functions</title>
879
+ <para>
880
+ Both, macros with arguments and <literal>static inline</>
881
+ functions, may be used. The latter are preferable if there are
882
+ multiple-evaluation hazards when written as a macro, as e.g. the
883
+ case with
884
+ <programlisting>
885
+ #define Max(x, y) ((x) > (y) ? (x) : (y))
886
+ </programlisting>
887
+ or when the macro would be very long. In other cases it's only
888
+ possible to use macros, or at least easier. For example because
889
+ expressions of various types need to be passed to the macro.
890
+ </para>
891
+ <para>
892
+ When the definition an inline function references symbols
893
+ (i.e. variables, functions) that are only available as part of the
894
+ backend, the function may not be visible when included from frontend
895
+ code.
896
+ <programlisting>
897
+ #ifndef FRONTEND
898
+ static inline MemoryContext
899
+ MemoryContextSwitchTo(MemoryContext context)
900
+ {
901
+ MemoryContext old = CurrentMemoryContext;
902
+
903
+ CurrentMemoryContext = context;
904
+ return old;
905
+ }
906
+ #endif /* FRONTEND */
907
+ </programlisting>
908
+ In this example <literal>CurrentMemoryContext</>, which is only
909
+ available in the backend, is referenced and the function thus
910
+ hidden with a <literal>#ifndef FRONTEND</literal>. This rule
911
+ exists because some compilers emit references to symbols
912
+ contained in inline functions even if the function is not used.
913
+ </para>
914
+ </simplesect>
915
+
916
+ <simplesect>
917
+ <title>Writing Signal Handlers</title>
918
+ <para>
919
+ To be suitable to run inside a signal handler code has to be
920
+ written very carefully. The fundamental problem is that, unless
921
+ blocked, a signal handler can interrupt code at any time. If code
922
+ inside the signal handler uses the same state as code outside
923
+ chaos may ensue. As an example consider what happens if a signal
924
+ handler tries to acquire a lock that's already held in the
925
+ interrupted code.
926
+ </para>
927
+ <para>
928
+ Barring special arrangements code in signal handlers may only
929
+ call async-signal safe functions (as defined in posix) and access
930
+ variables of type <literal>volatile sig_atomic_t</literal>. A few
931
+ functions in postgres are also deemed signal safe, importantly
932
+ <literal>SetLatch()</literal>.
933
+ </para>
934
+ <para>
935
+ In most cases signal handlers should do nothing more than note
936
+ that a signal has arrived, and wake up code running outside of
937
+ the handler using a latch. An example of such a handler is the
938
+ following:
939
+ <programlisting>
940
+ static void
941
+ handle_sighup(SIGNAL_ARGS)
942
+ {
943
+ int save_errno = errno;
944
+
945
+ got_SIGHUP = true;
946
+ SetLatch(MyLatch);
947
+
948
+ errno = save_errno;
949
+ }
950
+ </programlisting>
951
+ <literal>errno</> is safed and restored because
952
+ <literal>SetLatch()</> might change it. If that were not done
953
+ interrupted code that's currently inspecting errno might see the wrong
954
+ value.
955
+ </para>
956
+ </simplesect>
957
+
958
+ </sect1>
854
959
</chapter>
0 commit comments