--- al.c 2002/10/18 12:08:52 1.23
+++ al.c 2002/10/18 12:24:53 1.24
@@ -82,7 +82,8 @@
char *mem; /* reference to underlying chunk of data */
size_t size; /* size of underlying chunk of data */
int usecount; /* reference count (from al_chunk_t) */
- int freemem; /* boolean flag whether chunk of data has to be free(3)ed */
+ void (*freemem)(char *p, size_t n, void *u); /* callback function to reclaim memory when it is no longer referenced */
+ void *userdata; /* arbitrary pointer to pass context data to the callback function */
};
struct al_tx_st {
@@ -139,6 +140,17 @@
do { (alc)->begin -= n; (al)->bytes += (n); } while (0)
/*
+ * callback to release buffer memory allocated by the library
+ */
+static
+void freemem(char *p, size_t n, void *u)
+{
+printf("*** FREEMEM(LIBRARY) buffer %p size %d\n",p,n);
+ al_t *al = (al_t *)u;
+ (al->m.bfree)(p);
+}
+
+/*
* allocate backing store and its control structure from heap
*
* can be freed when usecount drops to zero
@@ -157,7 +169,8 @@
return AL_ERR_MEM;
}
- buf->freemem = 1;
+ buf->freemem = freemem;
+ buf->userdata = NULL;
buf->size = n;
buf->usecount = 0;
@@ -173,7 +186,7 @@
return AL_ERR_INT;
if (buf->freemem)
- (al->m.bfree)(buf->mem);
+ (buf->freemem)(buf->mem, buf->size, buf->userdata);
(al->m.free)(buf);
return AL_OK;
@@ -184,8 +197,8 @@
* and attach to existing memory
* only the control structure will be freed later
*/
-static al_rc_t
-make_buffer(al_t *al, char *p, size_t n, al_buffer_t **bufp)
+static
+al_rc_t make_buffer(al_t *al, char *p, size_t n, void (*freemem)(char *, size_t, void *), void *u, al_buffer_t **bufp)
{
al_buffer_t *buf;
@@ -194,7 +207,8 @@
buf->mem = p;
- buf->freemem = 0;
+ buf->freemem = freemem;
+ buf->userdata = u;
buf->size = n;
buf->usecount = 0;
@@ -539,8 +553,7 @@
* XXX - some list operations modify the buffer
*
*/
-al_rc_t
-al_attach_buffer(al_t *al, char *p, size_t n)
+al_rc_t al_attach_buffer(al_t *al, char *p, size_t n, void (*freemem)(char *, size_t, void *), void *u)
{
al_rc_t rc;
al_buffer_t *buf;
@@ -550,7 +563,7 @@
if (al == NULL || p == NULL || n < 0)
return AL_RC(AL_ERR_ARG);
- rc = make_buffer(al, p, n, &buf);
+ rc = make_buffer(al, p, n, freemem, u, &buf);
if (rc != AL_OK)
return AL_RC(rc);
rc = new_chunk(al,buf, &cur);
@@ -789,7 +802,7 @@
* - save traversal parameters
*/
al_rc_t
-al_traverse(al_t *al, al_tx_t *tx, size_t off, size_t n, al_td_t dir)
+al_traverse(al_t *al, size_t off, size_t n, al_td_t dir, al_tx_t *tx)
{
al_rc_t rc;
@@ -880,7 +893,7 @@
al_tx_t tx; /* XXX - private tx structure on stack */
al_chunk_t *view;
- rc = al_traverse(al, &tx, off, n, dir);
+ rc = al_traverse(al, off, n, dir, &tx);
if (rc != AL_OK)
return AL_RC(rc);
@@ -915,7 +928,7 @@
*lenp = 0; /* keep caller on safe side */
- rc = al_traverse(al, &tx, off, n, AL_FORWARD);
+ rc = al_traverse(al, off, n, AL_FORWARD, &tx);
if (rc != AL_OK)
return AL_RC(rc);
@@ -949,7 +962,7 @@
al_chunk_t *view;
size_t step;
- rc = al_traverse(al, &tx, off, n, AL_FORWARD);
+ rc = al_traverse(al, off, n, AL_FORWARD, &tx);
if (rc != AL_OK)
return AL_RC(rc);
|