Resource Pools
The primitive for creating a subpool is
make_sub_pool
,
which takes another pool
- the parent pool
- as an
argument. When the main pool
is cleared, the subpool will be
destroyed. The subpool may also be destroyed at any time, by
calling the function
destroy_pool()
.
This function will deallocate the entire pool.
Example
config_rec *c = NULL; pool *subpool = NULL; subpool = make_sub_pool(parent_pool); c = (config_rec *) pcalloc(subpool, sizeof(config_rec)); c->pool = subpool; ... destroy_pool(c->pool);
As you can see, you allocate a subpool first, then allocate the object
(in this case, a config_rec
) from that subpool. You then
store the pointer to the subpool in the appropriate field of the allocated
object, so that later, when that object is no longer needed, you can do
destroy_pool(c->pool);which will take care of the entire object.
If you make your own subpool, be sure to call destroy_pool()
once
you are completely finished with your subpool. As when using
malloc()
and free()
, if you allocate your own
subpool
s, then you are responsible for cleaning up after yourself.
Well, this not precisely the case; when your parent pool
is
destroyed, any subpools allocated from it, including your subpool, will
be destroyed as well.
On rare occasions, too-free use of
palloc()
and the
associated primitives may result in undesirably profligate resource
allocation. You can deal with such a case by creating a subpool, allocating
within the subpool rather than the main pool
, and clearing or
destroying the subpool, which releases the resources which were associated
with it. This really is a rare situation; the only case in which it
comes up in the standard module set is in case of listing directories, and
then only with very large directories. Unnecessary use of the
primitives discussed here can hair up your code quite a bit, with very little
gain.
Most Frequently Used Pools
The following are pool
s that already exist in the most common
structures within ProFTPD, and should be used for most purposes.
permanent_pool
Never ever ever allocate memory directly from
permanent_pool
using one of the p*()
pool
functions listed below. Instead, make a subpool, do what you need to, and
clear or destroy that subpool. permanent_pool
only gets cleared
rarely, on SIGHUP
and shutdown. Abuse of this pool will
lead to memory leaks.
Allocated: in
init_alloc()
,
when the master daemon first starts up, or catches a SIGHUP
Deallocated: automatically, when the master daemon calls
_exit()
server_rec->pool
Allocated: in
start_new_server()
, which is called if a <VirtualHost>
section is
encountered as the master parses the configuration file. As a special case,
the main_server
variable, the default "main" server,
is allocated in
init_config()
.
Deallocated: when forking a new server to handle an incoming connection,
that connection is handed the appropriate server_rec
, and all
other server_rec
s are destroyed. This occurs in the forked
child's process space, though; this prevents inter-server communication among
concurrent connections.
This pool
is also deallocated if a
SIGHUP
signal is received by the master daemon, all
server_rec->pool
s are destroyed in
main_rehash()
.
session_t->pool
Allocated: this pool
is not actually allocated, rather it
is set using the same pointer to permanent_pool
when the session
starts, in
fork_server()
.
This usage of the permanent_pool
pointer is an exception to the
normal rules of pool
usage. In this case, however, this pointer
assignment occurs after the process has
fork
ed, meaning that parent process' allocated heap memory
(along with the rest of the process image) is duplicated. It is this
duplicated memory space that the child process, via
session_t->pool
, is accessing, and not the long-running
(if using "ServerType standalone
") master daemon's
permanent_pool
.
Deallocated: this pool
, being a duplicate of, and not
synonymous with, permanent_pool
, is deallocated when the child
process exits.
session_t.xfer->pool
Allocated: in the
cmd_rnfr
command
handler, and the
_data_new_xfer()
function.
Deallocated: in
cmd_rnto
command
handler, if session.xfer.path
has not been set, if an error
occurred during the renaming of the file, or if the renaming succeeded. Also,
in
cmd_rnfr()
, prior
to reallocating the same pool, to clear out any previous use. And similarly
in
_data_new_xfer()
, prior to reallocating the same pointer, to clear out previous usage.
in
data_cleanup()
,
and in
data_abort()
--
see comment in code for these two functions.
conn_t->pool
Allocated: in either
inet_initialize_connection()
, a static function (need to track when this
is called -- I think by inet_create_connection, but why different from
inet_copy_connection?), or in
inet_copy_connection()
.
Deallocated: in
inet_close()
,
when a connection is done.
config_rec->pool
Allocated: in
add_config_set()
, called by the add_config_*()
functions. The parent
pool
is that of the containing server_rec
's set, at
the time when the configuration directive was parsed.
Deallocated: in
remove_config()
, or when the containing server_rec
's pool
is
destroyed.
cmd_rec->pool
Allocated: for configuration directives, this allocation occurs in
get_config_cmd()
, after a line has been read from the configuration file but before that
configuration command has been dispatched to its configuration handler.
For commands, the allocation occurs in
cmd_loop()
, before
dispatching to the appropriate command handler.
Deallocated: for configuration directives, this happens in
parse_config_file()
, after the configuration handler has returned. And, for commands, it
happens in
cmd_loop()
after
the command handler dispatch has returned.
cmd_rec->tmp_pool
_dispatch()
, prior
to the call to
log_add_run()
and the call to
call_module_cmd()
, which does the "dispatch" of the command to its handler(s).
call_module()
will also allocate this pool
, if it is not already present._dispatch()
, after
the command handler has returned, and after any possible handler errors are
dealt with.
Pool Functions