axis-c-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Thomas Gentsch ...@e-tge.de>
Subject Re: Memory handling in Axis2c server
Date Fri, 09 Jul 2010 12:07:50 GMT
On Fri, 2010-07-09 at 13:26 +0200, Akos Marton wrote:
> You had better send the corresponding code of the certain stack-trace.
> -can be interesting.

This is a bit more complicated because the code lives in multiple source
files ...
Initially I was rather thinking about "how is it supposed to work"?



Anyway, here is something like an "aggregated source code":

// My "business logic" which is a non-static C++ method of an C++ 
// object:
axiom_node_t * SoapSrv::invokeFunc(const axutil_env_t * env,
                                        axiom_node_t * node)
{
  if(axiom_node_get_node_type(node, env) == AXIOM_ELEMENT)
  {
    axiom_element_t * element = (axiom_element_t *)
                      axiom_node_get_data_element(node, env);
    if(element != NULL)
    {
      axis2_char_t * op_name = axiom_element_get_localname(element,
env);
      if(op_name == NULL)
      {
        // no server function ... log error
        return NULL;
      }

      axiom_node_t * respNode = NULL;

      DataObjectPtr req  = dataObjFromAxiom(node);
      DataObjectPtr resp = ... do something(op_name, req);
      respNode = dataObjToAxiom(resp);

      if(respNode == NULL)
      {
        // log error
      }
      return respNode;
    }
  }

  return NULL;
}

// To call the non-static method above I have wrapped this in
// a separate static function, which is registered with the server 
// skeleton:
extern "C" axiom_node_t * AXIS2_CALL soapSrvInvoke(
                                    axis2_svc_skeleton_t * skel,
                                    const axutil_env_t * env,
                                    axiom_node_t * node,
                                    axis2_msg_ctx_t * msg_ctx)
{
  return SoapSrv::getInstance()->invoke(skel, env, node, msg_ctx);
}

// and (this is actually not needed anymore but should not hurt):
axiom_node_t * SoapSrv::invoke(axis2_svc_skeleton_t * svc_skeleton,
                                    const axutil_env_t * env,
                                    axiom_node_t * node,
                                    axis2_msg_ctx_t * msg_ctx)
{
  return SoapSrv::getInstance()->invokeFunc(env, node);
}

// The axiom to SDO conversion:

axiom_node_t * Soap::dataObjToAxiom(DataObjectPtr o)
{
  if(m_ax == NULL)
  {
    m_ax = AxiomHelper::getHelper(getEnv());
  }

  axiom_document_t * doc = m_ax->toAxiomDoc(o);
  axiom_node_t * ret = (doc == NULL) ? NULL : 
    axiom_document_get_root_element(doc, m_ax->getEnv());
  return ret;
}

DataObjectPtr Soap::dataObjFromAxiom(axiom_node_t * n)
{
  if(m_ax == NULL)
  {
    m_ax = AxiomHelper::getHelper(getEnv());
  }
  return m_ax->toSdo(n, m_mdg);
}

Finally, the SDO AxiomHelper is attached.
Many thx!!
  tge


> 
> On Fri, Jul 9, 2010 at 1:02 PM, Thomas Gentsch <tg@e-tge.de> wrote:
> >
> > Hi all,
> >
> > I encountered a problem which I'm not sure how to handle - whether it is
> > my own fault because I did something wrong?
> >
> > I have a Axis2c server, which generally works nicely. The actual service
> > deals with Tuscany SDO objects, so I transform the Axiom objects to/from
> > SDOs when processing a request (this is actually a detail which should
> > not matter as the question is more general):
> >
> > In my service, I have something like this (following the example here:
> > http://www.dimuthu.org/blog/2008/10/02/understanding-apache-axis2c-services)
> >
> >> Service logic
> >> Just create a function with the following format.
> >> axiom_node_t *axis2_echo_echo(
> >>    const axutil_env_t * env,
> >>    axiom_node_t * input_node) {
> >>
> >>    /* Write your business logic Right Here */
> >> }
> >> Here you extract out the input parameters from the the input_node and
> >> build the return node based on your output parameters. (Note that even
> >> though this is an echo example you can’t return the same input node as
> >> the output node, instead you have to replicate the input node and
> >> return it to avoid the double freeing)
> >
> > So I create a returned axiom_node_t but eventually end up with a memory
> > leak:
> > ------------------
> > ==3461== 20,164 (40 direct, 20,124 indirect) bytes in 1 blocks are
> > definitely lost in loss record 975 of 980
> > ==3461==    at 0x4025C1C: malloc (vg_replace_malloc.c:195)
> > ==3461==    by 0x47C1CFC: axutil_allocator_malloc_impl (allocator.c:75)
> > ==3461==    by 0x47A2E1C: axiom_stax_builder_create
> > (om_stax_builder.c:70)
> > ==3461==    by 0x4712A66:
> > commonj::sdo_axiom::AxiomHelper::toAxiomDoc(commonj::sdo::RefCountingPointer<commonj::sdo::DataObject>,
char const*, char const*) (sdo_axiom.cpp:146)
> > ==3461==    by 0x4438CB8:
> > dataObjToAxiom(commonj::sdo::RefCountingPointer<commonj::sdo::DataObject>)
(in /opt/bes/itm/modules/libimsoap.so)
> > ==3461==    by 0x4439839: invokeFunc(axutil_env const*, axiom_node*)
> > (im_soapsrv.cpp:160)
> > ==3461==    by 0x4439396: invoke(axis2_svc_skeleton*, axutil_env const*,
> > axiom_node*, axis2_msg_ctx*) (im_soapsrv.cpp:79)
> > ==3461==    by 0x4C31C8D: soapSrvInvoke (im_soapsrvax.cpp:37)
> > ==3461==    by 0x474B0D6:
> > axis2_raw_xml_in_out_msg_recv_invoke_business_logic_sync
> > (raw_xml_in_out_msg_recv.c:209)
> > ==3461==    by 0x474A433: axis2_msg_recv_invoke_business_logic
> > (msg_recv.c:481)
> > ==3461==    by 0x474AB34: axis2_msg_recv_receive_impl (msg_recv.c:403)
> > ==3461==    by 0x474A4B3: axis2_msg_recv_receive (msg_recv.c:520)
> > ------------------
> >
> > Who is going to free the axiom_node_t I return? In theory this must
> > happen inside of Axis2c when serializing the data to the network, right?
> > So, there is actually nothing I can do?
> > Under which circumstances might this not be done?
> > Am I possibly doing something wrong?
> >
> >
> > Secondly, how is it supposed to work the other way around? In my
> > service, I receive an axiom node, transform it to a SDO etc.
> > Who is in charge of freeing the original axiom_node_t?
> > I don't do it in my code, so the result is another memory leak:
> >
> > -----------------------
> > ==3461== 8,737 (56 direct, 8,681 indirect) bytes in 1 blocks are
> > definitely lost in loss record 970 of 980
> > ==3461==    at 0x4025C1C: malloc (vg_replace_malloc.c:195)
> > ==3461==    by 0x47C1CFC: axutil_allocator_malloc_impl (allocator.c:75)
> > ==3461==    by 0x47A022B: axiom_output_create (om_output.c:79)
> > ==3461==    by 0x4712381:
> > commonj::sdo_axiom::AxiomHelper::toSdo(axiom_node*,
> > commonj::sdo::RefCountingPointer<commonj::sdo::DataFactory>, char
> > const*) (sdo_axiom.cpp:214)
> > ==3461==    by 0x4438D9F: dataObjFromAxiom(axiom_node*)
> > (in /opt/bes/itm/modules/libimsoap.so)
> > ==3461==    by 0x44397C0: invokeFunc(axutil_env const*, axiom_node*)
> > (im_soapsrv.cpp:152)
> > ==3461==    by 0x4439396: invoke(axis2_svc_skeleton*, axutil_env const*,
> > axiom_node*, axis2_msg_ctx*) (im_soapsrv.cpp:79)
> > ==3461==    by 0x4C31C8D: soapSrvInvoke (im_soapsrvax.cpp:37)
> > ==3461==    by 0x474B0D6:
> > axis2_raw_xml_in_out_msg_recv_invoke_business_logic_sync
> > (raw_xml_in_out_msg_recv.c:209)
> > ==3461==    by 0x474A433: axis2_msg_recv_invoke_business_logic
> > (msg_recv.c:481)
> > ==3461==    by 0x474AB34: axis2_msg_recv_receive_impl (msg_recv.c:403)
> > ==3461==    by 0x474A4B3: axis2_msg_recv_receive (msg_recv.c:520)
> > -----------------------
> >
> > Any hints are greatly appreciated!!
> >
> > Many thx + regards,
> >  tge
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: c-user-unsubscribe@axis.apache.org
> > For additional commands, e-mail: c-user-help@axis.apache.org
> >
> >
> 
> 
> 



Mime
View raw message