You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-user@axis.apache.org by Stadelmann Josef <jo...@axa-winterthur.ch> on 2008/01/15 11:26:24 UTC
execute axiom_document_free(om_document,env); // and my hash_table key/val pairs are gone
Hi Developers,
I use Apache Axis2/C version 1.0.0, ported to OopenVMS, also used on Windows 2000
under VS 2005 (C/C++); so far greate stuff.
Now I have the follwoing problem and I think it is a bug in Axis2/C
I have to deserialize my payload (build om from xml) and return to updated pointers
to two hash tables, each keeping a set of fldnam (key) and fldval (val->value) pairs.
The xml payload to be converted into an om model looks like this
<root xmlns:e="element" xmlns:ws="workspace" xmlns:col="collection">
<col:wscol>
<ws:wsinp>
<e:blah01>yuck01</e:blah01>
<e:blah02>yuck02</e:blah02>
<e:blah03>yuck03</e:blah03>
<e:blah04>yuck04</e:blah04>
</ws:wsinp>
<ws:wsold>
<e:blah11>yuck11</e:blah11>
<e:blah12>yuck12</e:blah12>
<e:blah13>yuck13</e:blah13>
<e:blah14>yuck14</e:blah14>
</ws:wsold>
</col:wscol>
</root>
The clue is that I can iterate over the hash tables and find my key/value pairs but only
as long as I do not execute axiom_document_free(om_document,env); as done in code below.
Once this call is executed, pointers to hash tables are still as before, but content, key
and value pairs are gone, do no longer exist, and my routine writes out some rubbish. why?
I asume this is a bug OR do I something wrong allocating storage for the hash tables
key / value pairs?
What has to be released from memeory (deallocated), I guess only the om model as I want
it but not the key and values of my hash tables.
And BTW, if one knows a faster way to deserialize my payload as I do it, just let me know.
I will be very thank-full, because I am still a xml/om newby.
Thanks for information and regards
axis2_bool_t AXIS2_CALL
axawl_deserialize_input_payload(axutil_env_t *env,
const axis2_char_t *payload_inp,
const axutil_hash_t **pphtwsinp,
const axutil_hash_t **pphtwsold)
{
int retval = 0;
unsigned __int16 scnt;
char *tval2;
long ii;
const axis2_char_t *encoding = ENCODING; //#define ENCODING "ISO-8859-1"
// const axis2_char_t *uri = AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI;
axiom_xml_reader_t *xml_reader = NULL;
axiom_stax_builder_t *om_builder = NULL;
axiom_document_t *om_document = NULL;
axiom_node_t *root_node = NULL;
axiom_node_t *body = NULL;
axiom_node_t *root = NULL;
axiom_node_t *wscol = NULL;
axiom_node_t *ws = NULL;
axiom_node_t *wsinp = NULL;
axiom_node_t *wsold = NULL;
axiom_node_t *wsout = NULL;
axiom_node_t *ele = NULL;
axiom_children_qname_iterator_t *children_iter = NULL;
axis2_char_t *fldnam = NULL;
a *fldval = NULL;
const void *key = NULL;
void *val = NULL;
axutil_hash_index_t *hi;
axutil_hash_t *htwsinp = NULL;
axutil_hash_t *htwsold = NULL;
int status = AXIS2_SUCCESS;
env->log->level = AXIS2_LOG_LEVEL_DEBUG;
AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, " %s %d", "deserialize input payload", 2);
scnt = strlen(payload_inp);
/** create the parser ---- here we feed our P1 parameter = the input argument in string form */
xml_reader = axiom_xml_reader_create_for_memory(env, payload_inp, scnt, encoding, AXIS2_XML_PARSER_TYPE_BUFFER);
if (!xml_reader) {
printf("%s \n", axutil_error_get_message(env->error));
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s", axutil_error_get_message(env->error));
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s", "unable to create xml_reader");
return AXIS2_FAILURE;
}
om_builder = axiom_stax_builder_create(env, xml_reader);
if (!om_builder) {
axiom_xml_reader_free(xml_reader, env);
printf("%s \n", axutil_error_get_message(env->error));
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s", axutil_error_get_message(env->error));
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s", "unable to create om_builder - ERROR CREATING PULLPARSER");
return AXIS2_FAILURE;
}
/**
create an om document
document is the container of om model created using builder
*/
om_document = axiom_stax_builder_get_document(om_builder, env);
if (!om_document) {
axiom_xml_reader_free(xml_reader, env);
printf("%s \n", axutil_error_get_message(env->error));
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s", axutil_error_get_message(env->error));
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s", "unable to create axiom document");
return AXIS2_FAILURE;
}
root_node = axiom_document_get_root_element(om_document, env);
if(!root_node)
{
axiom_stax_builder_free(om_builder, env);
printf("%s \n", axutil_error_get_message(env->error));
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s", axutil_error_get_message(env->error));
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s", "unable to create root node from om_document");
return AXIS2_FAILURE;
}
#ifdef __DEBUG__
lib$signal(SS$_DEBUG);
#endif
/**
Pseudo Code to reflect what shall happen
for each wscol in soap_body
// we get c:root only
for each ws in wscol
// we get c:Text c:wsout c:wsold c:wsinp
for each ele in ws
// we get d:fldnam with fldval as text
next ele
next ws
next
**/
/**
pre-condition: we have the document with the OM model in it
action: we loop over the (sub-)tree and isolates the workspace collection, the workpsaces and
the elements in it. workspace nodes are used to identify and create a corresponding hash table
and then all elements in the workspace-node are loaded as key and value pairs to hash tables
post-condition: after the loop terminates, we have hash tables established and tow are populated
with key-value-pairs of strings; we have a hash table for wsinp, wsold and later wsout and htGWKSP
But htwsout and htGWKSP are not established here as the intention of the code is jsut to deserialize
for ws input and ws old (used to establish the process context, set process context to previous state
when client calls in again)
**/
// for (root = axiom_soap_body_get_base_node(soap_body, env);root;root = axiom_node_get_next_sibling(root, env)) {
for (root = axiom_document_get_root_element(om_document, env);root;root = axiom_node_get_next_sibling(root, env)) {
putnode(root, env);
for (wscol = axiom_node_get_first_child(root, env);wscol;wscol = axiom_node_get_next_sibling(wscol, env)) {
putnode(wscol, env);
for (ws = axiom_node_get_first_child(wscol, env);ws; ws = axiom_node_get_next_sibling(ws, env)) {
putnode(ws, env);
for (ele = axiom_node_get_first_child(ws, env);ele;ele = axiom_node_get_next_sibling(ele, env)) {
switch (getWorkspaceID(ele, env)) {
case 1:
if(!wsinp)
wsinp = ws;
if (!htwsinp)
htwsinp = axutil_hash_make(env);
fldval = (a *) AXIS2_MALLOC(env->allocator, sizeof(a));
fldval->value = getFLDVAL(ele, env);
fldnam = getFLDNAM(ele, env);
printf("\nfldval->value : %s",fldval->value);
printf("\nfldnam : %s",fldnam);
axutil_hash_set(htwsinp, fldnam, AXIS2_HASH_KEY_STRING, fldval);
break;
case 2:
if(!wsold)
wsold = ws;
if (!htwsold)
htwsold = axutil_hash_make(env);
fldval = (a *) AXIS2_MALLOC(env->allocator, sizeof(a));
fldval->value = getFLDVAL(ele, env);
fldnam = getFLDNAM(ele, env);
printf("\nfldval->value : %s",fldval->value);
printf("\nfldnam : %s",fldnam);
axutil_hash_set(htwsold, fldnam, AXIS2_HASH_KEY_STRING, fldval);
break;
default:
break;
}
}
}
}
}
for (hi = axutil_hash_first(htwsinp, env); hi; hi = axutil_hash_next(env, hi)) {
axutil_hash_this(hi, &key, NULL, &val);
printf("\nkey\t: %s", key);
printf("\tval\t: %s", ((a *) val)->value);
}
/**
QUESTION: do we need the parsed in document and om model any longer?
NO - we can safely free all of it, memory space and we create a new
om_document with om as root wscol ws and elements in it later, after
the warpper returns.
**/
axiom_document_free(om_document,env);
for (hi = axutil_hash_first(htwsinp, env); hi; hi = axutil_hash_next(env, hi)) {
axutil_hash_this(hi, &key, NULL, &val);
printf("\nkey\t: %s", key);
printf("\tval\t: %s", ((a *) val)->value);
}
/**
let us update all our hash_table_pointers to use the hash_tables after we
return to the caller of this routine.
**/
*pphtwsinp = htwsinp;
*pphtwsold = htwsold;
return AXIS2_SUCCESS;
}
AW: AW: execute axiom_document_free(om_document, env); // and my hash_table key/val pairs are gone
Posted by Stadelmann Josef <jo...@axa-winterthur.ch>.
-----Ursprüngliche Nachricht-----
Von: Senaka Fernando [mailto:senaka@wso2.com]
Gesendet: Dienstag, 15. Januar 2008 18:59
An: Apache AXIS C User List
Cc: axis-c-dev@ws.apache.org
Betreff: Re: AW: execute axiom_document_free(om_document, env); // and
my hash_table key/val pairs are gone
Hi Josef,
The builder & document logic is as follows. The document will always have
a builder and the builder is responsible for creating the document. That
is why it doesn't make sense to free only the document. Reconstructing a
document would involve reconstructing a builder.
It would be better if you could attach the stack trace from your debugger
to diagnose the exact problem, but as far as I know, when you create a
copy of your hash table, the values inside it are simply passed as shallow
copies. That means, your duplicated string resides on the heap and the
hash will have a reference. When you copy your hash, the old as well as
the new one will have the same reference. Then, when you free one, the
other would rather be having a dangling pointer.
The workaround is to change the way you duplicate your hash and get onto
safe grounds. You'd create your hash copy from scratch and iterate through
your original hash and add element by element to the new hash. You can
then do the duplication of strings and create deep copies. This can be
sort of a tedious process. You can get help by reading through the hash.c
source file and see how the hash is copied.
There might not be a bug in the existing implementation in terms of the
way the hashes are copied, because we can't force a user to always
allocate objects on the heap because shallow copies are much faster. Thus,
if a user wishes to do heap allocations and at the same time to duplicate
hashes, he will rather have to override the default behavior.
I believe this might solve your issue. But, I can't guarantee as I have
not seen the exact stack trace or the point at which it breaks.
++> Hi Fernando,
you'r absolut correct, I went into axutil_hash code and it is as you say;
copy a hash table is not a deep copy but a shalow copy and dangling is very
likely to occure with multiple hash tables;
maybe we have some day axutil_hash_copy_deep() to overcome such problems.
It is also nonsens from a OO point of view, given a hash_table is beeing
seen as an instance of an class in which case freeing one hash obj
should/would not touche the other's hash obj's strings (key/val's)
Thanks for the fine answer, I have my problem under control now, and it
is as it is, if you are aware about something (say if it is documented)
best by example code which did not just run throug an editor, then your
most of the time fine. But thanks again.
Josef
Hi Devs,
Please correct me if this should not be the desired behavior. And, if it
is not, this is invariably a bug in the way we copy hashes. Also, please
note that it is documented that axutil_hash_copy() creates a shallow copy.
And, I have assumed that the documentation justifies the logic I speak of.
However, I believe that even if this logic is justifiable it is strongly
recommended that we should introduce another method
axutil_hash_copy_deep() that does a deep copy instead of a shallow copy.
What do you say?
Regards,
Senaka
> Your call correct, it works now but shows a new problem, that of
> freeing two of the 4 hash tables later.
>
> freeing the om_document with
> axiom_stax_builder_free(om_builder,env);
> seams to work,
>
>
> But freeing a builder when you think you have to free the om_document
> is not so obvious; but you are righth the creator of my om_document
> is the axiom_stax_builder with its get_document.
>
> However this allone does not solve the problem. They still exists.
>
> Until one really does a
>
> fldval = (a *) AXIS2_MALLOC(env->allocator, sizeof(a));
> fldval->value = axutil_strdup(env,getFLDVAL(ele, env));
> fldnam = axutil_strdup(env,getFLDNAM(ele, env));
>
> and used the axutil_strdup function; fldval and fldnam are then
> added to the hash tables and I just hope that freeing the hash
> tables deallocates this string space too;
>
> Here I have my doubts because when I do
>
> axutil_hash_free(htwsinp,env);
> axutil_hash_free(htwsold,env);
> //axutil_hash_free(htGWKSP,env);
> //axutil_hash_free(htwsout,env);
>
>
> only htwsinp and htwsold can bee freed, while htGWKSP and htwsout
> result in a exception asking me to break or continue in VS 2005
>
> So please here is the code used to make htGWKSP
>
> /**
> puts htwsinp hash table into htGWKSP, does like obbput in CORBA world
> the ponter to the golbal hash table htGWKSP is updated
> **/
> axis2_bool_t AXIS2_CALL
> axawl_put(const axutil_hash_t *htwsinp,
> const axutil_env_t *env,
> const axutil_hash_t **pphtGWKSP) //!< load Spin elements into global
> workspace
> {
> axutil_hash_t *htGWKSP = NULL;
> axutil_hash_index_t *hi;
>
> const void *key = NULL;
> void *val = NULL;
>
> htGWKSP = *pphtGWKSP;
> if (htGWKSP)
> axutil_hash_free(htGWKSP,env);
>
> htGWKSP = axutil_hash_copy(htwsinp, env);
> printf("\n\nDump htGWKSP - a copy of htwsinp to htGWKSP - the
> traditional obbput()");
> AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "%s",
> "\n\nDump htGWKSP - a copy of htwsinp to htGWKSP - the
> traditional obbput()");
> for (hi = axutil_hash_first(htwsinp, env); hi; hi =
> axutil_hash_next(env, hi)) {
> axutil_hash_this(hi, &key, NULL, &val);
> printf("\nkey\t: %s", key);
> printf("\tval\t: %s", ((a *) val)->value);
> AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "%s", key);
> AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "%s", ((a *) val)->value);
> }
> (*pphtGWKSP) = htGWKSP;
> return AXIS2_SUCCESS;
> }
>
>
> Now tell me why I can not use
>
> axutil_hash_free(htGWKSP,env);
>
> without getting an error raised?
>
> And the same is true for htwsout which is a copy of htGWKSP before we
> return to the caller.
> htwsout must be freed after reconstructing the AXIOM document and then
> serializing it into
> the payload string to be returned from my SPg-Legacy.c server to its
> client through axis2.
>
> Thanks and regards
> Josef.Stadelmann@
> axa-winterthur.ch
>
>
> -----Ursprüngliche Nachricht-----
> Von: Samisa Abeysinghe [mailto:samisa@wso2.com]
> Gesendet: Dienstag, 15. Januar 2008 15:52
> An: Apache AXIS C User List
> Betreff: Re: execute axiom_document_free(om_document, env); // and my
> hash_table key/val pairs are gone
>
>
> Senaka Fernando wrote:
>> 2. Consider duplicating the strings before copying to (or from) your
>> hash.
>> You can use axutil_strdup() for this purpose.
>>
>
> Yes, this may solve your problems. I skimmed through the code given, and
> it looks to me you are using the shallow copies returned by the OM
> element accessor methods and store them in hashes without duplicating
> them.
>
> Thanks,
> Samisa...
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: axis-c-user-unsubscribe@ws.apache.org
> For additional commands, e-mail: axis-c-user-help@ws.apache.org
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: axis-c-user-unsubscribe@ws.apache.org
> For additional commands, e-mail: axis-c-user-help@ws.apache.org
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: axis-c-user-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-c-user-help@ws.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: axis-c-user-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-c-user-help@ws.apache.org
Re: AW: execute axiom_document_free(om_document,
env); // and my hash_table key/val pairs are gone
Posted by Senaka Fernando <se...@wso2.com>.
Hi Josef,
The builder & document logic is as follows. The document will always have
a builder and the builder is responsible for creating the document. That
is why it doesn't make sense to free only the document. Reconstructing a
document would involve reconstructing a builder.
It would be better if you could attach the stack trace from your debugger
to diagnose the exact problem, but as far as I know, when you create a
copy of your hash table, the values inside it are simply passed as shallow
copies. That means, your duplicated string resides on the heap and the
hash will have a reference. When you copy your hash, the old as well as
the new one will have the same reference. Then, when you free one, the
other would rather be having a dangling pointer.
The workaround is to change the way you duplicate your hash and get onto
safe grounds. You'd create your hash copy from scratch and iterate through
your original hash and add element by element to the new hash. You can
then do the duplication of strings and create deep copies. This can be
sort of a tedious process. You can get help by reading through the hash.c
source file and see how the hash is copied.
There might not be a bug in the existing implementation in terms of the
way the hashes are copied, because we can't force a user to always
allocate objects on the heap because shallow copies are much faster. Thus,
if a user wishes to do heap allocations and at the same time to duplicate
hashes, he will rather have to override the default behavior.
I believe this might solve your issue. But, I can't guarantee as I have
not seen the exact stack trace or the point at which it breaks.
Hi Devs,
Please correct me if this should not be the desired behavior. And, if it
is not, this is invariably a bug in the way we copy hashes. Also, please
note that it is documented that axutil_hash_copy() creates a shallow copy.
And, I have assumed that the documentation justifies the logic I speak of.
However, I believe that even if this logic is justifiable it is strongly
recommended that we should introduce another method
axutil_hash_copy_deep() that does a deep copy instead of a shallow copy.
What do you say?
Regards,
Senaka
> Your call correct, it works now but shows a new problem, that of
> freeing two of the 4 hash tables later.
>
> freeing the om_document with
> axiom_stax_builder_free(om_builder,env);
> seams to work,
>
>
> But freeing a builder when you think you have to free the om_document
> is not so obvious; but you are righth the creator of my om_document
> is the axiom_stax_builder with its get_document.
>
> However this allone does not solve the problem. They still exists.
>
> Until one really does a
>
> fldval = (a *) AXIS2_MALLOC(env->allocator, sizeof(a));
> fldval->value = axutil_strdup(env,getFLDVAL(ele, env));
> fldnam = axutil_strdup(env,getFLDNAM(ele, env));
>
> and used the axutil_strdup function; fldval and fldnam are then
> added to the hash tables and I just hope that freeing the hash
> tables deallocates this string space too;
>
> Here I have my doubts because when I do
>
> axutil_hash_free(htwsinp,env);
> axutil_hash_free(htwsold,env);
> //axutil_hash_free(htGWKSP,env);
> //axutil_hash_free(htwsout,env);
>
>
> only htwsinp and htwsold can bee freed, while htGWKSP and htwsout
> result in a exception asking me to break or continue in VS 2005
>
> So please here is the code used to make htGWKSP
>
> /**
> puts htwsinp hash table into htGWKSP, does like obbput in CORBA world
> the ponter to the golbal hash table htGWKSP is updated
> **/
> axis2_bool_t AXIS2_CALL
> axawl_put(const axutil_hash_t *htwsinp,
> const axutil_env_t *env,
> const axutil_hash_t **pphtGWKSP) //!< load Spin elements into global
> workspace
> {
> axutil_hash_t *htGWKSP = NULL;
> axutil_hash_index_t *hi;
>
> const void *key = NULL;
> void *val = NULL;
>
> htGWKSP = *pphtGWKSP;
> if (htGWKSP)
> axutil_hash_free(htGWKSP,env);
>
> htGWKSP = axutil_hash_copy(htwsinp, env);
> printf("\n\nDump htGWKSP - a copy of htwsinp to htGWKSP - the
> traditional obbput()");
> AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "%s",
> "\n\nDump htGWKSP - a copy of htwsinp to htGWKSP - the
> traditional obbput()");
> for (hi = axutil_hash_first(htwsinp, env); hi; hi =
> axutil_hash_next(env, hi)) {
> axutil_hash_this(hi, &key, NULL, &val);
> printf("\nkey\t: %s", key);
> printf("\tval\t: %s", ((a *) val)->value);
> AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "%s", key);
> AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "%s", ((a *) val)->value);
> }
> (*pphtGWKSP) = htGWKSP;
> return AXIS2_SUCCESS;
> }
>
>
> Now tell me why I can not use
>
> axutil_hash_free(htGWKSP,env);
>
> without getting an error raised?
>
> And the same is true for htwsout which is a copy of htGWKSP before we
> return to the caller.
> htwsout must be freed after reconstructing the AXIOM document and then
> serializing it into
> the payload string to be returned from my SPg-Legacy.c server to its
> client through axis2.
>
> Thanks and regards
> Josef.Stadelmann@
> axa-winterthur.ch
>
>
> -----Ursprüngliche Nachricht-----
> Von: Samisa Abeysinghe [mailto:samisa@wso2.com]
> Gesendet: Dienstag, 15. Januar 2008 15:52
> An: Apache AXIS C User List
> Betreff: Re: execute axiom_document_free(om_document, env); // and my
> hash_table key/val pairs are gone
>
>
> Senaka Fernando wrote:
>> 2. Consider duplicating the strings before copying to (or from) your
>> hash.
>> You can use axutil_strdup() for this purpose.
>>
>
> Yes, this may solve your problems. I skimmed through the code given, and
> it looks to me you are using the shallow copies returned by the OM
> element accessor methods and store them in hashes without duplicating
> them.
>
> Thanks,
> Samisa...
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: axis-c-user-unsubscribe@ws.apache.org
> For additional commands, e-mail: axis-c-user-help@ws.apache.org
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: axis-c-user-unsubscribe@ws.apache.org
> For additional commands, e-mail: axis-c-user-help@ws.apache.org
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: axis-c-user-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-c-user-help@ws.apache.org
Re: AW: execute axiom_document_free(om_document,
env); // and my hash_table key/val pairs are gone
Posted by Senaka Fernando <se...@wso2.com>.
Hi Josef,
The builder & document logic is as follows. The document will always have
a builder and the builder is responsible for creating the document. That
is why it doesn't make sense to free only the document. Reconstructing a
document would involve reconstructing a builder.
It would be better if you could attach the stack trace from your debugger
to diagnose the exact problem, but as far as I know, when you create a
copy of your hash table, the values inside it are simply passed as shallow
copies. That means, your duplicated string resides on the heap and the
hash will have a reference. When you copy your hash, the old as well as
the new one will have the same reference. Then, when you free one, the
other would rather be having a dangling pointer.
The workaround is to change the way you duplicate your hash and get onto
safe grounds. You'd create your hash copy from scratch and iterate through
your original hash and add element by element to the new hash. You can
then do the duplication of strings and create deep copies. This can be
sort of a tedious process. You can get help by reading through the hash.c
source file and see how the hash is copied.
There might not be a bug in the existing implementation in terms of the
way the hashes are copied, because we can't force a user to always
allocate objects on the heap because shallow copies are much faster. Thus,
if a user wishes to do heap allocations and at the same time to duplicate
hashes, he will rather have to override the default behavior.
I believe this might solve your issue. But, I can't guarantee as I have
not seen the exact stack trace or the point at which it breaks.
Hi Devs,
Please correct me if this should not be the desired behavior. And, if it
is not, this is invariably a bug in the way we copy hashes. Also, please
note that it is documented that axutil_hash_copy() creates a shallow copy.
And, I have assumed that the documentation justifies the logic I speak of.
However, I believe that even if this logic is justifiable it is strongly
recommended that we should introduce another method
axutil_hash_copy_deep() that does a deep copy instead of a shallow copy.
What do you say?
Regards,
Senaka
> Your call correct, it works now but shows a new problem, that of
> freeing two of the 4 hash tables later.
>
> freeing the om_document with
> axiom_stax_builder_free(om_builder,env);
> seams to work,
>
>
> But freeing a builder when you think you have to free the om_document
> is not so obvious; but you are righth the creator of my om_document
> is the axiom_stax_builder with its get_document.
>
> However this allone does not solve the problem. They still exists.
>
> Until one really does a
>
> fldval = (a *) AXIS2_MALLOC(env->allocator, sizeof(a));
> fldval->value = axutil_strdup(env,getFLDVAL(ele, env));
> fldnam = axutil_strdup(env,getFLDNAM(ele, env));
>
> and used the axutil_strdup function; fldval and fldnam are then
> added to the hash tables and I just hope that freeing the hash
> tables deallocates this string space too;
>
> Here I have my doubts because when I do
>
> axutil_hash_free(htwsinp,env);
> axutil_hash_free(htwsold,env);
> //axutil_hash_free(htGWKSP,env);
> //axutil_hash_free(htwsout,env);
>
>
> only htwsinp and htwsold can bee freed, while htGWKSP and htwsout
> result in a exception asking me to break or continue in VS 2005
>
> So please here is the code used to make htGWKSP
>
> /**
> puts htwsinp hash table into htGWKSP, does like obbput in CORBA world
> the ponter to the golbal hash table htGWKSP is updated
> **/
> axis2_bool_t AXIS2_CALL
> axawl_put(const axutil_hash_t *htwsinp,
> const axutil_env_t *env,
> const axutil_hash_t **pphtGWKSP) //!< load Spin elements into global
> workspace
> {
> axutil_hash_t *htGWKSP = NULL;
> axutil_hash_index_t *hi;
>
> const void *key = NULL;
> void *val = NULL;
>
> htGWKSP = *pphtGWKSP;
> if (htGWKSP)
> axutil_hash_free(htGWKSP,env);
>
> htGWKSP = axutil_hash_copy(htwsinp, env);
> printf("\n\nDump htGWKSP - a copy of htwsinp to htGWKSP - the
> traditional obbput()");
> AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "%s",
> "\n\nDump htGWKSP - a copy of htwsinp to htGWKSP - the
> traditional obbput()");
> for (hi = axutil_hash_first(htwsinp, env); hi; hi =
> axutil_hash_next(env, hi)) {
> axutil_hash_this(hi, &key, NULL, &val);
> printf("\nkey\t: %s", key);
> printf("\tval\t: %s", ((a *) val)->value);
> AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "%s", key);
> AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "%s", ((a *) val)->value);
> }
> (*pphtGWKSP) = htGWKSP;
> return AXIS2_SUCCESS;
> }
>
>
> Now tell me why I can not use
>
> axutil_hash_free(htGWKSP,env);
>
> without getting an error raised?
>
> And the same is true for htwsout which is a copy of htGWKSP before we
> return to the caller.
> htwsout must be freed after reconstructing the AXIOM document and then
> serializing it into
> the payload string to be returned from my SPg-Legacy.c server to its
> client through axis2.
>
> Thanks and regards
> Josef.Stadelmann@
> axa-winterthur.ch
>
>
> -----Ursprüngliche Nachricht-----
> Von: Samisa Abeysinghe [mailto:samisa@wso2.com]
> Gesendet: Dienstag, 15. Januar 2008 15:52
> An: Apache AXIS C User List
> Betreff: Re: execute axiom_document_free(om_document, env); // and my
> hash_table key/val pairs are gone
>
>
> Senaka Fernando wrote:
>> 2. Consider duplicating the strings before copying to (or from) your
>> hash.
>> You can use axutil_strdup() for this purpose.
>>
>
> Yes, this may solve your problems. I skimmed through the code given, and
> it looks to me you are using the shallow copies returned by the OM
> element accessor methods and store them in hashes without duplicating
> them.
>
> Thanks,
> Samisa...
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: axis-c-user-unsubscribe@ws.apache.org
> For additional commands, e-mail: axis-c-user-help@ws.apache.org
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: axis-c-user-unsubscribe@ws.apache.org
> For additional commands, e-mail: axis-c-user-help@ws.apache.org
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: axis-c-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-c-dev-help@ws.apache.org
AW: execute axiom_document_free(om_document, env); // and my hash_table key/val pairs are gone
Posted by Stadelmann Josef <jo...@axa-winterthur.ch>.
Your call correct, it works now but shows a new problem, that of
freeing two of the 4 hash tables later.
freeing the om_document with
axiom_stax_builder_free(om_builder,env);
seams to work,
But freeing a builder when you think you have to free the om_document
is not so obvious; but you are righth the creator of my om_document
is the axiom_stax_builder with its get_document.
However this allone does not solve the problem. They still exists.
Until one really does a
fldval = (a *) AXIS2_MALLOC(env->allocator, sizeof(a));
fldval->value = axutil_strdup(env,getFLDVAL(ele, env));
fldnam = axutil_strdup(env,getFLDNAM(ele, env));
and used the axutil_strdup function; fldval and fldnam are then
added to the hash tables and I just hope that freeing the hash
tables deallocates this string space too;
Here I have my doubts because when I do
axutil_hash_free(htwsinp,env);
axutil_hash_free(htwsold,env);
//axutil_hash_free(htGWKSP,env);
//axutil_hash_free(htwsout,env);
only htwsinp and htwsold can bee freed, while htGWKSP and htwsout
result in a exception asking me to break or continue in VS 2005
So please here is the code used to make htGWKSP
/**
puts htwsinp hash table into htGWKSP, does like obbput in CORBA world
the ponter to the golbal hash table htGWKSP is updated
**/
axis2_bool_t AXIS2_CALL
axawl_put(const axutil_hash_t *htwsinp,
const axutil_env_t *env,
const axutil_hash_t **pphtGWKSP) //!< load Spin elements into global workspace
{
axutil_hash_t *htGWKSP = NULL;
axutil_hash_index_t *hi;
const void *key = NULL;
void *val = NULL;
htGWKSP = *pphtGWKSP;
if (htGWKSP)
axutil_hash_free(htGWKSP,env);
htGWKSP = axutil_hash_copy(htwsinp, env);
printf("\n\nDump htGWKSP - a copy of htwsinp to htGWKSP - the traditional obbput()");
AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "%s",
"\n\nDump htGWKSP - a copy of htwsinp to htGWKSP - the traditional obbput()");
for (hi = axutil_hash_first(htwsinp, env); hi; hi = axutil_hash_next(env, hi)) {
axutil_hash_this(hi, &key, NULL, &val);
printf("\nkey\t: %s", key);
printf("\tval\t: %s", ((a *) val)->value);
AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "%s", key);
AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "%s", ((a *) val)->value);
}
(*pphtGWKSP) = htGWKSP;
return AXIS2_SUCCESS;
}
Now tell me why I can not use
axutil_hash_free(htGWKSP,env);
without getting an error raised?
And the same is true for htwsout which is a copy of htGWKSP before we return to the caller.
htwsout must be freed after reconstructing the AXIOM document and then serializing it into
the payload string to be returned from my SPg-Legacy.c server to its client through axis2.
Thanks and regards
Josef.Stadelmann@
axa-winterthur.ch
-----Ursprüngliche Nachricht-----
Von: Samisa Abeysinghe [mailto:samisa@wso2.com]
Gesendet: Dienstag, 15. Januar 2008 15:52
An: Apache AXIS C User List
Betreff: Re: execute axiom_document_free(om_document, env); // and my
hash_table key/val pairs are gone
Senaka Fernando wrote:
> 2. Consider duplicating the strings before copying to (or from) your hash.
> You can use axutil_strdup() for this purpose.
>
Yes, this may solve your problems. I skimmed through the code given, and
it looks to me you are using the shallow copies returned by the OM
element accessor methods and store them in hashes without duplicating them.
Thanks,
Samisa...
---------------------------------------------------------------------
To unsubscribe, e-mail: axis-c-user-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-c-user-help@ws.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: axis-c-user-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-c-user-help@ws.apache.org
Re: execute axiom_document_free(om_document, env); // and my
hash_table key/val pairs are gone
Posted by Samisa Abeysinghe <sa...@wso2.com>.
Senaka Fernando wrote:
> 2. Consider duplicating the strings before copying to (or from) your hash.
> You can use axutil_strdup() for this purpose.
>
Yes, this may solve your problems. I skimmed through the code given, and
it looks to me you are using the shallow copies returned by the OM
element accessor methods and store them in hashes without duplicating them.
Thanks,
Samisa...
---------------------------------------------------------------------
To unsubscribe, e-mail: axis-c-user-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-c-user-help@ws.apache.org
Re: execute axiom_document_free(om_document,
env); // and my hash_table key/val pairs are gone
Posted by Senaka Fernando <se...@wso2.com>.
Hi Josef,
I have two suggestion for your plea.
1. You should consider calling axiom_stax_builder_free() instead of
axiom_document_free(). As the stax_builder is responsible for the returned
document.
2. Consider duplicating the strings before copying to (or from) your hash.
You can use axutil_strdup() for this purpose.
NOTE: duplicating strings allocate new memory. Please be responsible to
free allocated memory to avoid leaks.
AFAIK, according to what you describe, this doesn't seem to be a bug.
Regards,
Senaka
> Hi Developers,
>
> I use Apache Axis2/C version 1.0.0, ported to OopenVMS, also used on
> Windows 2000
> under VS 2005 (C/C++); so far greate stuff.
>
> Now I have the follwoing problem and I think it is a bug in Axis2/C
>
> I have to deserialize my payload (build om from xml) and return to updated
> pointers
> to two hash tables, each keeping a set of fldnam (key) and fldval
> (val->value) pairs.
>
> The xml payload to be converted into an om model looks like this
>
> <root xmlns:e="element" xmlns:ws="workspace" xmlns:col="collection">
> <col:wscol>
> <ws:wsinp>
> <e:blah01>yuck01</e:blah01>
> <e:blah02>yuck02</e:blah02>
> <e:blah03>yuck03</e:blah03>
> <e:blah04>yuck04</e:blah04>
> </ws:wsinp>
> <ws:wsold>
> <e:blah11>yuck11</e:blah11>
> <e:blah12>yuck12</e:blah12>
> <e:blah13>yuck13</e:blah13>
> <e:blah14>yuck14</e:blah14>
> </ws:wsold>
> </col:wscol>
> </root>
>
> The clue is that I can iterate over the hash tables and find my key/value
> pairs but only
> as long as I do not execute axiom_document_free(om_document,env); as
> done in code below.
>
> Once this call is executed, pointers to hash tables are still as before,
> but content, key
> and value pairs are gone, do no longer exist, and my routine writes out
> some rubbish. why?
>
> I asume this is a bug OR do I something wrong allocating storage for the
> hash tables
> key / value pairs?
>
> What has to be released from memeory (deallocated), I guess only the om
> model as I want
> it but not the key and values of my hash tables.
>
> And BTW, if one knows a faster way to deserialize my payload as I do it,
> just let me know.
> I will be very thank-full, because I am still a xml/om newby.
>
> Thanks for information and regards
>
>
>
> axis2_bool_t AXIS2_CALL
> axawl_deserialize_input_payload(axutil_env_t *env,
> const axis2_char_t *payload_inp,
> const axutil_hash_t **pphtwsinp,
> const axutil_hash_t **pphtwsold)
> {
> int retval = 0;
> unsigned __int16 scnt;
> char *tval2;
> long ii;
>
> const axis2_char_t *encoding = ENCODING; //#define ENCODING "ISO-8859-1"
> // const axis2_char_t *uri = AXIOM_SOAP12_SOAP_ENVELOPE_NAMESPACE_URI;
>
>
> axiom_xml_reader_t *xml_reader = NULL;
> axiom_stax_builder_t *om_builder = NULL;
> axiom_document_t *om_document = NULL;
> axiom_node_t *root_node = NULL;
>
> axiom_node_t *body = NULL;
> axiom_node_t *root = NULL;
> axiom_node_t *wscol = NULL;
> axiom_node_t *ws = NULL;
> axiom_node_t *wsinp = NULL;
> axiom_node_t *wsold = NULL;
> axiom_node_t *wsout = NULL;
> axiom_node_t *ele = NULL;
>
> axiom_children_qname_iterator_t *children_iter = NULL;
>
> axis2_char_t *fldnam = NULL;
> a *fldval = NULL;
>
> const void *key = NULL;
> void *val = NULL;
> axutil_hash_index_t *hi;
> axutil_hash_t *htwsinp = NULL;
> axutil_hash_t *htwsold = NULL;
>
> int status = AXIS2_SUCCESS;
>
> env->log->level = AXIS2_LOG_LEVEL_DEBUG;
> AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, " %s %d", "deserialize input
> payload", 2);
>
> scnt = strlen(payload_inp);
>
> /** create the parser ---- here we feed our P1 parameter = the input
> argument in string form */
> xml_reader = axiom_xml_reader_create_for_memory(env, payload_inp,
> scnt, encoding, AXIS2_XML_PARSER_TYPE_BUFFER);
> if (!xml_reader) {
> printf("%s \n", axutil_error_get_message(env->error));
> AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s",
> axutil_error_get_message(env->error));
> AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s", "unable to create
> xml_reader");
> return AXIS2_FAILURE;
> }
>
> om_builder = axiom_stax_builder_create(env, xml_reader);
> if (!om_builder) {
> axiom_xml_reader_free(xml_reader, env);
> printf("%s \n", axutil_error_get_message(env->error));
> AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s",
> axutil_error_get_message(env->error));
> AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s", "unable to create
> om_builder - ERROR CREATING PULLPARSER");
> return AXIS2_FAILURE;
> }
>
> /**
> create an om document
> document is the container of om model created using builder
> */
> om_document = axiom_stax_builder_get_document(om_builder, env);
> if (!om_document) {
> axiom_xml_reader_free(xml_reader, env);
> printf("%s \n", axutil_error_get_message(env->error));
> AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s",
> axutil_error_get_message(env->error));
> AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s", "unable to create
> axiom document");
> return AXIS2_FAILURE;
> }
>
> root_node = axiom_document_get_root_element(om_document, env);
> if(!root_node)
> {
> axiom_stax_builder_free(om_builder, env);
> printf("%s \n", axutil_error_get_message(env->error));
> AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s",
> axutil_error_get_message(env->error));
> AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "%s", "unable to create
> root node from om_document");
> return AXIS2_FAILURE;
> }
>
> #ifdef __DEBUG__
> lib$signal(SS$_DEBUG);
> #endif
> /**
> Pseudo Code to reflect what shall happen
> for each wscol in soap_body
> // we get c:root only
> for each ws in wscol
> // we get c:Text c:wsout c:wsold c:wsinp
> for each ele in ws
> // we get d:fldnam with fldval as text
> next ele
> next ws
> next
> **/
>
> /**
> pre-condition: we have the document with the OM model in it
>
> action: we loop over the (sub-)tree and isolates the workspace
> collection, the workpsaces and
> the elements in it. workspace nodes are used to identify and create a
> corresponding hash table
> and then all elements in the workspace-node are loaded as key and
> value pairs to hash tables
>
> post-condition: after the loop terminates, we have hash tables
> established and tow are populated
> with key-value-pairs of strings; we have a hash table for wsinp, wsold
> and later wsout and htGWKSP
> But htwsout and htGWKSP are not established here as the intention of the
> code is jsut to deserialize
> for ws input and ws old (used to establish the process context, set
> process context to previous state
> when client calls in again)
> **/
>
>
> // for (root = axiom_soap_body_get_base_node(soap_body, env);root;root =
> axiom_node_get_next_sibling(root, env)) {
> for (root = axiom_document_get_root_element(om_document,
> env);root;root = axiom_node_get_next_sibling(root, env)) {
> putnode(root, env);
> for (wscol = axiom_node_get_first_child(root, env);wscol;wscol =
> axiom_node_get_next_sibling(wscol, env)) {
> putnode(wscol, env);
> for (ws = axiom_node_get_first_child(wscol, env);ws; ws =
> axiom_node_get_next_sibling(ws, env)) {
> putnode(ws, env);
> for (ele = axiom_node_get_first_child(ws, env);ele;ele =
> axiom_node_get_next_sibling(ele, env)) {
> switch (getWorkspaceID(ele, env)) {
> case 1:
> if(!wsinp)
> wsinp = ws;
> if (!htwsinp)
> htwsinp = axutil_hash_make(env);
> fldval = (a *) AXIS2_MALLOC(env->allocator,
> sizeof(a));
> fldval->value = getFLDVAL(ele, env);
> fldnam = getFLDNAM(ele, env);
> printf("\nfldval->value : %s",fldval->value);
> printf("\nfldnam : %s",fldnam);
> axutil_hash_set(htwsinp, fldnam,
> AXIS2_HASH_KEY_STRING, fldval);
> break;
> case 2:
> if(!wsold)
> wsold = ws;
> if (!htwsold)
> htwsold = axutil_hash_make(env);
> fldval = (a *) AXIS2_MALLOC(env->allocator,
> sizeof(a));
> fldval->value = getFLDVAL(ele, env);
> fldnam = getFLDNAM(ele, env);
> printf("\nfldval->value : %s",fldval->value);
> printf("\nfldnam : %s",fldnam);
> axutil_hash_set(htwsold, fldnam,
> AXIS2_HASH_KEY_STRING, fldval);
> break;
> default:
> break;
> }
> }
> }
> }
> }
>
> for (hi = axutil_hash_first(htwsinp, env); hi; hi = axutil_hash_next(env,
> hi)) {
> axutil_hash_this(hi, &key, NULL, &val);
> printf("\nkey\t: %s", key);
> printf("\tval\t: %s", ((a *) val)->value);
> }
> /**
> QUESTION: do we need the parsed in document and om model any
> longer?
> NO - we can safely free all of it, memory space and we create a
> new
> om_document with om as root wscol ws and elements in it later,
> after
> the warpper returns.
> **/
> axiom_document_free(om_document,env);
>
> for (hi = axutil_hash_first(htwsinp, env); hi; hi = axutil_hash_next(env,
> hi)) {
> axutil_hash_this(hi, &key, NULL, &val);
> printf("\nkey\t: %s", key);
> printf("\tval\t: %s", ((a *) val)->value);
> }
>
> /**
> let us update all our hash_table_pointers to use the hash_tables after
> we
> return to the caller of this routine.
> **/
> *pphtwsinp = htwsinp;
> *pphtwsold = htwsold;
>
> return AXIS2_SUCCESS;
> }
>
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: axis-c-user-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-c-user-help@ws.apache.org