add some whitespace, add section on accessing globals

git-svn-id: https://svn.php.net/repository/phpdoc/en/trunk@260840 c90b9560-bf6c-de11-be94-00142212c4b1
This commit is contained in:
Gwynne Raskind 2008-06-06 10:07:37 +00:00
parent 4b23ef594a
commit 51eca8e6ea

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!-- $Revision: 1.3 $ -->
<!-- $Revision: 1.4 $ -->
<sect1 xml:id="internals2.structure.globals" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Extension globals</title>
@ -11,7 +11,9 @@
accessed from any function without any extra declaration. These traditional
globals have a few drawbacks:
</simpara>
<itemizedlist>
<listitem>
<simpara>
Barring any special options passed to the compiler, a global varaible can
@ -19,17 +21,21 @@
whether or not that code should be doing so.
</simpara>
</listitem>
<listitem>
<simpara>
A typical global variable is not thread safe.
</simpara>
</listitem>
<listitem>
<simpara>
The names of global variables are as global as the variables themselves.
</simpara>
</listitem>
</itemizedlist>
<simpara>
A PHP extension's globals are more properly called the "extension state",
since most modules must remember what they're doing between function calls.
@ -38,6 +44,7 @@
Zend and PHP might do something like this in <filename>counter.c</filename>
to store that value:
</simpara>
<example xml:id="internals2.structure.globals.intro.wrong-way">
<title>The wrong way to store the basic counter interface's value</title>
<programlisting role="c">
@ -54,6 +61,7 @@ PHP_FUNCTION(counter_get)
]]>
</programlisting>
</example>
<simpara>
On the surface this appears a viable solution, and indeed in a simple test
it would function correctly. However, there are a number of situations in
@ -83,6 +91,7 @@ PHP_FUNCTION(counter_get)
module is simply <literal>"counter"</literal>. Here is the global structure
declaration from <filename>php_counter.h</filename>:
</simpara>
<example xml:id="internals2.structure.globals.declaring.doth">
<title>The counter module's globals</title>
<programlisting role="c">
@ -93,9 +102,11 @@ ZEND_END_MODULE_GLOBALS(counter)
]]>
</programlisting>
</example>
<simpara>
And this is the declaration from <filename>counter.c</filename>:
</simpara>
<example xml:id="internals2.structure.globals.declaring.dotc">
<title>The counter module's global structure declaration</title>
<programlisting role="c">
@ -106,6 +117,65 @@ ZEND_DECLARE_MODULE_GLOBALS(counter)
</example>
</sect2>
<sect2 xml:id="internals2.structure.globals.using">
<title>Accessing module globals</title>
<simpara>
As discussed above, per-module globals are declared inside a C structure
whose name is obscured by Zend macros. As a result, the ideal way to access
members of this structure is by the use of further macros. Accordingly, most
if not all extensions which have globals have a declaration like this
somewhere in their header file:
</simpara>
<example xml:id="internals2.structure.globals.using.accessor">
<title>Accessor macros for per-module globals</title>
<programlisting role="c">
<![CDATA[
#ifdef ZTS
#define COUNTER_G(v) TSRMG(counter_globals_id, zend_counter_globals *, v)
#else
#define COUNTER_G(v) (counter_globals.v)
#endif
]]>
</programlisting>
</example>
<note>
<simpara>
This could have been generalized into a macro of its own by the Zend API,
but as of PHP 5.3 (and PHP 6 at the time of this writing), that hasn't
happened. The global accessor construct is written into the header by
<command>ext_skel</command> and thus is generally left alone by extension
writers, unless they wish to change the name of the accessor macro.
</simpara>
</note>
<note>
<simpara>
<constant>COUNTER_G</constant> was the name given to the macro by
<command>ext_skel</command>, but it's not necessary for it to have that
name and could just as easily be called <literal>FOO</literal> instead.
</simpara>
</note>
<simpara>
Any code in the counter extension that accesses a global must thus wrap it
in the macro <constant>COUNTER_G</constant>.
</simpara>
<warning>
<simpara>
Any function which accesses globals must either be declared by Zend macros,
have <constant>TSRMLS_DC</constant> as its last argument, or call the macro
<constant>TSRMLS_FETCH</constant> before accessing the globals. See
<!--<link linkend="internals2.memory.tsrm">-->the TSRM documentation<!--</link>--> for
more information.
</simpara>
</warning>
</sect2>
</sect1>