more explanation of auto-init system

This was SVN commit r1097.
This commit is contained in:
janwas 2004-09-02 02:46:50 +00:00
parent 8a19257cd4
commit 71b62dc484
2 changed files with 36 additions and 2 deletions

View File

@ -152,7 +152,10 @@ int clipboard_free(wchar_t* copy)
///////////////////////////////////////////////////////////////////////////////
// each module has the linker add a pointer to its init and shutdown
// init and shutdown mechanism: register a function to be called at
// pre-main init or shutdown.
//
// each module has the linker add a pointer to its init or shutdown
// function to a table (at a user-defined position).
// zero runtime overhead, and there's no need for a central dispatcher
// that knows about all the modules.
@ -163,9 +166,23 @@ int clipboard_free(wchar_t* copy)
// - initialize via constructor. however, that would leave the problem of
// shutdown order and timepoint, which is also taken care of here.
// - register init/shutdown functions from a NLSO constructor:
// clunky, and setting order is more complicated.
// clunky, and setting order is more difficult.
// - on-demand initialization: complicated; don't know in what order
// things happen. also, no way to determine how long init takes.
//
// the "segment name" determines when and in what order the functions are
// called: "LIB$W{type}{group}", where {type} is either I for
// (pre-main) initializers, or T for terminators (last of the atexit handlers).
// {group} is [B, Y]; groups are called in alphabetical order, but
// call order within the group itself is unspecified.
//
// define the segment via #pragma data_seg(name), register any functions
// to be called via WIN_REGISTER_FUNC, and then restore the previous segment
// with #pragma data_seg() .
//
// note: group must be [B, Y]. data declared in groups A or Z may
// be placed beyond the table start/end by the linker, since the linker's
// ordering WRT other source files' data is undefined within a segment.
typedef int(*_PIFV)(void);

View File

@ -313,9 +313,26 @@ extern void win_unlock(uint idx);
}
///////////////////////////////////////////////////////////////////////////////
// init and shutdown mechanism: register a function to be called at
// pre-main init or shutdown.
// the "segment name" determines when and in what order the functions are
// called: "LIB$W{type}{group}", where {type} is either I for
// (pre-main) initializers, or T for terminators (last of the atexit handlers).
// {group} is [B, Y]; groups are called in alphabetical order, but
// call order within the group itself is unspecified.
//
// define the segment via #pragma data_seg(name), register any functions
// to be called via WIN_REGISTER_FUNC, and then restore the previous segment
// with #pragma data_seg() .
#define WIN_REGISTER_FUNC(func) static int func(); static int(*p##func)(void) = func
#define WIN_SAVE_LAST_ERROR DWORD last_err__ = GetLastError();
#define WIN_RESTORE_LAST_ERROR STMT(if(last_err__ != 0 && GetLastError() == 0) SetLastError(last_err__););