Hi.

I made a plugin. it's almost same to null-transform plugin but has one more
function.

it gets and delivers one of query string to transform so that it can sends
on defined bit per second according to the value from each http
transaction's query string.

The difference between my plugin and null-transform is i made one more
creation of continuation.

In null-transform :

TSPluginInit
 |
 |---------------> TSContCreate(transform_plugin)
                             |
                             |---------------->transform_plugin
                                                        |
                                                        |---------------->
TSTransformCreate(null-transform) <---------- associate my data to
transform itself.


In my plugin

TSPluginInit
 |
 |---------------> TSContCreate(transform_plugin)
                             |
                             |---------------->transform_plugin
                                                        |
                                                        |---------------->
TSContCreate(txn_cont_handler)   <------------------- one more creation of
continuation and associate a value from query string to this continuation.

                 |

                 |--------------------------> txn_cont_handler

                                                          |


|-----------------------------> TSTransformCreate(null-transform)  <---------
get the value from parent continuation



                  and associate it to myself.


Why did i create one more continuation?

In the beginning i associated a value from query string to parent
continuation in null-transform then made transform to get the value from
the parent continuation. but i found other http requests overwrite the
value in the parent continuation before the transform get the value from
parent continuation!! so i hooked onto TS_EVENT_HTTP_TXN_START and made an
grandpa continuation. so that the parent from grandpa continuation can
keeps it's own value from the http transaction.

at first it looks fine. it worked well. but when i repeated tests and
checked memory leak. i found something wrong. the memory leak happens and
finally traffic server down showing "insufficient memory". I did same test
for null-transform and memory leak never happened.

Of course i appended TSContDestroy as i created one more continuation. I
repeated comparing null-transform and new-transform. i think i followed the
steps after creation of continuation. I can't find what's wrong.

This is cut out code(i'd like to remind you it's almost same to
null-transform) : (if you wanna run my plugin i can send it. it's very
simple code but you can see memory leak.)
...
static void
transform_add(TSHttpTxn txnp)
{
  TSVConn connp;

  // create a transform here!!
  connp = TSTransformCreate(null_transform, txnp);
  TSHttpTxnHookAdd(txnp, TS_HTTP_RESPONSE_TRANSFORM_HOOK, connp);
}

static int
txn_cont_handler(TSCont contp, TSEvent event, void *edata)
{
TSHttpTxn txnp = (TSHttpTxn) edata;

switch (event) {
case TS_EVENT_HTTP_READ_REQUEST_HDR :
...
TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
return 0;
case TS_EVENT_HTTP_CACHE_LOOKUP_COMPLETE :
// ready to create transform
transform_add(txnp);
TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
return 0;
case TS_EVENT_HTTP_READ_RESPONSE_HDR :
if (transformable(txnp)) {
// ready to create transform
transform_add(txnp);
}
TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
return 0;
case TS_EVENT_HTTP_TXN_CLOSE :
// Destroy continuation here!!!
   TSContDestroy(contp);
TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
return 0;
default :
break;
}
return 0;
}

static int
h264_transform_plugin(TSCont contp, TSEvent event, void *edata)
{
  TSHttpTxn txnp = (TSHttpTxn) edata;
  TSCont txn_contp;

  switch (event) {
case TS_EVENT_HTTP_TXN_START :
// Create parent continuation one more instead of creation of transform!!
txn_contp = TSContCreate(txn_cont_handler, NULL);
TSHttpTxnHookAdd(txnp, TS_HTTP_READ_REQUEST_HDR_HOOK, txn_contp);
TSHttpTxnHookAdd(txnp, TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK, txn_contp);
TSHttpTxnHookAdd(txnp, TS_HTTP_READ_RESPONSE_HDR_HOOK, txn_contp);
TSHttpTxnHookAdd(txnp, TS_HTTP_TXN_CLOSE_HOOK, txn_contp);
TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
return 0;
default:
break;
  }

  return 0;
}

void
TSPluginInit(int argc, const char *argv[])
{
  TSPluginRegistrationInfo info;
  TSCont contp;

// make a grandpa continuation
contp = TSContCreate(h264_transform_plugin, NULL);

// to save of query string
TSHttpHookAdd(TS_HTTP_TXN_START_HOOK, contp);

  return;
}

Reply via email to