mod_annot editor

Annotate Section

Generalised Memory Management

APR provides builtin functions for managing memory, and a few other basic resources such as files, sockets, and mutexes. But there is no requirement to use these. An alternative is to use native allocation functions, and explicitly register a cleanup with the pool:


	mytype* myvar = malloc(sizeof(mytype)) ;
	apr_pool_cleanup_register(pool, myvar, free, apr_pool_cleanup_null) ;

or

	FILE* f = fopen(filename, "r") ;
	apr_pool_cleanup_register(pool, f, fclose, apr_pool_cleanup_null) ;

will delegate responsibility for cleanup to the pool, so that no further action from the programmer is required. But bear in mind that native functions may be less portable than APR equivalents.

This method generalises to resources opaque to Apache and APR. For example, to open a database connection and ensure it is closed after use:


	MYSQL* sql = NULL ;
	sql = mysql_init(sql) ;
	if ( sql == NULL ) { log error and return failure ; }
	apr_pool_cleanup_register(pool, sql, mysql_close,
		apr_pool_cleanup_null) ;

	sql = mysql_real_connect(sql, host, user, pass, dbname, port, sock, 0) ;
	if ( sql == NULL ) { log error and return failure ; }

Note that APR provides an altogether better method for managing database connections - this will be the subject of another article.

As a second example, consider XML processing:


	xmlDocPtr doc = xmlReadFile(filename) 
	apr_pool_cleanup_register(pool, doc, xmlFreeDoc,
		apr_pool_cleanup_null) ;

	/* now do things with doc, that may allocate further memory
	   managed by the XML library but will be cleaned by xmlFreeDoc
	*/

Integrating C++ destructor-cleanup code provides yet another example:
Suppose we have:


	class myclass {
	public:
  	  virtual ~myclass() { do cleanup ; }
  	  // ....
	} ;

We define a C wrapper:

	void myclassCleanup(void* ptr) { delete (myclass*)ptr ; }

and register it with the pool when we allocate myclass:

	myclass* myobj = new myclass(...) ;
	apr_pool_cleanup_register(pool, (void*)myobj, myclassCleanup,
		apr_pool_cleanup_null) ;

	// now we've hooked our existing resource management from C++
	// into apache and never need to delete myobj