Login
Username:

Password:

Remember me



Lost Password?

Register now!
Main Menu
H3D.org Feeds
H3D.org Forum Index
   Programming Issues
     Strange behavior from ResourceResolver and URNs in H3D 2.2b
Register To Post

Threaded | Newest First Previous Topic | Next Topic | Bottom
Poster Thread
karlsvec
Posted on: 2012/5/19 2:08
Quite a regular
Joined: 2008/7/1
From:
Posts: 41
Strange behavior from ResourceResolver and URNs in H3D 2.2b
Hello,

I'm using H3D 2.2 beta and trying to programmatically set up some custom URNs for my application, but I'm getting some very weird behavior from ResourceResolver. Here's some sort-of pseudocode that illustrates the problem:

ResourceResolver::setURNResolver( new URNResolver );

ResourceResolver::getURNResolver()->addURNResolveRule"my_namespace",
                                                       
"my_prefix",
                                                       
"/path/to/x3d/files" );

// test the URN resolver
std::cout << "resolved URN: " << ResourceResolver::getURNResolver()->resolveURN"urn:my_namespace:my_prefix/test.x3d" );
std::cout << std::endl;

// test ResourceResolver::resolveURLAsFile()
std::cout << "resolved URL: " << ResourceResolver::resolveURLAsFile"urn:my_namespace:my_prefix/test.x3d" );
std::cout << std::endl;


I get the following output:

resolved URN: /path/to/x3d/files/test.x3d
resolved URL
:


I expect ResourceResolver::resolveUrlAsFile() to have the same output as URNResolver::resolveURN(), but it doesn't. After running this code in a debugger, I see that inside the call to resolveUrlAsFile(), the call to urn_resolver().get() always returns zero, even though clearly the AutoRef<> object *does* contain a valid pointer.

string ResourceResolver::resolveURLAs( const string &urn,
                                       
bool *is_tmp_file,
                                       
bool folder ) {
  if( 
urn == "" ) return "";
  
string filename urn;
  if( 
urn_resolver().get() ) { // <--- this always returns zero, even if a URNResolver is set
    
filename urn_resolver()->resolveURNurn );
  }
  
  
// first try as relative path


Of course, this has me very confused. Am I somehow misusing ResourceResolver and/or URNResolver?

My toolchain is MinGW GCC 4.6.2 on Windows 7. I understand that MinGW is not an officially supported compiler (and that is why I haven't reported this on the bug tracker), but I haven't had any problems with a MinGW-built libH3DAPI.dll up to this point. Is it possible I've run into a compiler bug? Presumably, wouldn't people using GCC 4.6.2 on other platforms have the same problem (assuming they're trying to use URNs)?

I did mention that I'm using the 2.2 beta branch of H3D, but the ResourceResolver code seems unchanged from the 2.1 branch, so I assume I'd have the same problem there.

Any thoughts on this issue are greatly appreciated. I'm more than willing to try out any patches folks might come up with.

Thanks,

- Karl
Markus
Posted on: 2012/5/21 9:41
Webmaster
Joined: 2006/3/27
From: SenseGraphics
Posts: 1903
Re: Strange behavior from ResourceResolver and URNs in H3D 2.2b
I am guessing that H3D::initializeH3D() in H3DApi.cpp for some reason is called after you already set a new urn-resolver. Could you check that this is not the case?

Other than that I can only suspect some assumed static initialization order or something along that road.

How did you debug that it never enters
if( urn_resolver().get() ) { // <--- this always returns zero, even if a URNResolver is set 
    
filename urn_resolver()->resolveURNurn ); 
  }

cerr? step into (if that is possible with ming)? or somehow else?
karlsvec
Posted on: 2012/5/21 21:41
Quite a regular
Joined: 2008/7/1
From:
Posts: 41
Re: Strange behavior from ResourceResolver and URNs in H3D 2.2b
Quote:

How did you debug that it never enters
if( urn_resolver().get() ) { // <--- this always returns zero, even if a URNResolver is set  
    
filename urn_resolver()->resolveURNurn );  
  }

cerrstep into (if that is possible with ming)? or somehow else?



I'm using GDB 7.3.1 from MinGW and set a breakpoint.

Quote:

I am guessing that H3D::initializeH3D() in H3DApi.cpp for some reason is called after you already set a new urn-resolver. Could you check that this is not the case?


H3D::initializeH3D() is being called only once, on program start-up.

Quote:

Other than that I can only suspect some assumed static initialization order or something along that road.


It does look like some sort of static initialization problem. I set a breakpoint in ResourceResolver::urn_resolver() in ResourceResolver.h to see what the value of urn_resolver is after each call:

static auto_ptrURNResolver > & urn_resolver() {
    static 
auto_ptrURNResolver urn_resolver(NULL);
    return 
urn_resolver// <--- breakpoint here
}


It seems that when the call to urn_resolver() comes from ResourceResolver::getURNResolver(), things work as expected. However, the direct call to urn_resolver() from ResourceResolver::resolveURLAs() either causes the static urn_resolver instance to be re-initialized, or it's returning an entirely new instance.

EDIT: Adding another call to ResourceResolver::getURNResolver() after the call to ResourceResolver::resolveURLAs() returns my original URNResolver instance! So it appears that the call to urn_resolver() in ResourceResolver::resolveURLAs() *does* in fact return a new URNResolver instance.

Any ideas for workarounds? It seems to me that the motivation for putting the urn_resolver static initialization into ResourceResolver::urn_resolver() is so that subclasses of ResourceResolver have their own distinct static instance of URNResolver. Is there a way to move to static initialization somewhere else without breaking things?

Thanks,

- Karl

SECOND EDIT: I created the following workaround:
Index: include/H3D/ResourceResolver.h
===================================================================
--- include/
H3D/ResourceResolver.h    (revision 1924)
+++ include/
H3D/ResourceResolver.h    (working copy)
@@ -
131,+131,@@
                                 
bool folder );
     
     static 
auto_ptrURNResolver > & urn_resolver() {
-      static 
auto_ptrURNResolver urn_resolver(NULL);
-      return 
urn_resolver;
+      return 
urnresolver;
     }
     
     static 
H3DUtil::AutoPtrVectorResourceResolver > & resolvers() {
@@ -
142,+141,@@
     
     static 
string baseURL;
     static 
TmpFileNameList tmp_files;
+    static 
auto_ptrURNResolver urnresolver;
   };
 }
 
Indexsrc/ResourceResolver.cpp
===================================================================
--- 
src/ResourceResolver.cpp    (revision 1924)
+++ 
src/ResourceResolver.cpp    (working copy)
@@ -
44,+44,@@
 
 
string ResourceResolver::baseURL"" );
 
ResourceResolver::TmpFileNameList ResourceResolver::tmp_files;
+
auto_ptrURNResolver ResourceResolver::urnresolverNULL );
 
 
string ResourceResolver::resolveURLAs( const string &urn,
                                        
bool *is_tmp_file,


Since I only need one URNResolver instance in my application, this works just fine.
Markus
Posted on: 2012/5/22 9:12
Webmaster
Joined: 2006/3/27
From: SenseGraphics
Posts: 1903
Re: Strange behavior from ResourceResolver and URNs in H3D 2.2b
To me it seems like a bug, only one urn-resolver should exist.
Could I bother you to create a short test case and submit a bug report?
karlsvec
Posted on: 2012/5/22 20:48
Quite a regular
Joined: 2008/7/1
From:
Posts: 41
Re: Strange behavior from ResourceResolver and URNs in H3D 2.2b
Yes, I will put together and submit a test case against H3D trunk, since the ResourceResolver code is the same as in 2.2 beta.
karlu
Posted on: 2012/5/29 9:13
Guru
Joined: 2004/12/2
From: Sweden
Posts: 758
Re: Strange behavior from ResourceResolver and URNs in H3D 2.2b
The patch above seems to revert a patch I sent you to fix a "Static initialization order fiasco". The static auto_ptr might not have been initialized when first used, and might seem to point at a valid object since it has not yet been set to NULL.


----------------
KJ Lundin Palmerius
C Research
Linköping University, Sweden

karlsvec
Posted on: 2012/5/29 23:05
Quite a regular
Joined: 2008/7/1
From:
Posts: 41
Re: Strange behavior from ResourceResolver and URNs in H3D 2.2b
Quote:
The patch above seems to revert a patch I sent you to fix a "Static initialization order fiasco".


My forum notifications and inbox are empty, so I don't think I ever received the patch you sent. Or did you send it via email?

I agree that in my example patch I do not initialize the static auto_ptr properly. I've edited that post accordingly.
karlu
Posted on: 2012/5/30 10:31
Guru
Joined: 2004/12/2
From: Sweden
Posts: 758
Re: Strange behavior from ResourceResolver and URNs in H3D 2.2b
I miswrote, thought I replied to Markus. The patch was sent to SenseGraphics and implemented the function static variable as a remidy to the static initialization order problem.

The initialization cannot be global since there are other objects created globally that rely on the resolver already being initialized at that point. It was only when I updated the compiler that the problem appeared.


----------------
KJ Lundin Palmerius
C Research
Linköping University, Sweden

karlsvec
Posted on: 2012/6/7 22:08
Quite a regular
Joined: 2008/7/1
From:
Posts: 41
Re: Strange behavior from ResourceResolver and URNs in H3D 2.2b
Ok, I think I have the problem worked out.

I believe that having the ResourceResolver::urn_resolver() method definition in class scope was causing it to be inlined by GCC. This in turn results in two separate "copies" of the inlined urn_resolver() method -- one in H3DAPI, and one in my code. Calling getURNResolver() returns my URNResolver instance, but the call to resolveURLAs() returns the "copy" owned by H3DAPI.

This patch fixed things for me:
Index: include/H3D/ResourceResolver.h
===================================================================
--- include/
H3D/ResourceResolver.h    (revision 1927)
+++ include/
H3D/ResourceResolver.h    (working copy)
@@ -
130,10 +130,@@
                                 
bool *is_tmp_file,
                                 
bool folder );
     
-    static 
auto_ptrURNResolver > & urn_resolver() {
-      static 
auto_ptrURNResolver urn_resolver(NULL);
-      return 
urn_resolver;
-    }
+    static 
auto_ptrURNResolver > & urn_resolver();
     
     static 
H3DUtil::AutoPtrVectorResourceResolver > & resolvers() {
       static 
H3DUtil::AutoPtrVectorResourceResolver resolvers;
Indexsrc/ResourceResolver.cpp
===================================================================
--- 
src/ResourceResolver.cpp    (revision 1927)
+++ 
src/ResourceResolver.cpp    (working copy)
@@ -
140,+140,@@

   }
   return 
false;
 }
+
+
auto_ptrURNResolver > & ResourceResolver::urn_resolver() {
+  static 
auto_ptrURNResolver urn_resolverNULL );
+  return 
urn_resolver;
+}


I can still submit a test case demonstrating the old behavior to the Mantis tracker, but given the trivial nature of the patch, it seems unnecessary to me (and I can't imagine that this patch would break things for other compilers).

Should I submit a test case along with this patch, or just the patch itself?

Many thanks,

- Karl
Markus
Posted on: 2012/6/29 10:14
Webmaster
Joined: 2006/3/27
From: SenseGraphics
Posts: 1903
Re: Strange behavior from ResourceResolver and URNs in H3D 2.2b
The patch will be fine in this case. If you refer to this forum post in your bug report it would be good, for more information.
(1) 2 »
Threaded | Newest First Previous Topic | Next Topic | Top

Register To Post
 



(C) 2012 SenseGraphics AB    ---    Powered by XOOPS