From: Kirk, B. (JSC-EG311) <ben...@na...> - 2013-04-03 16:43:37
|
On Apr 3, 2013, at 11:28 AM, Derek Gaston <fri...@gm...> wrote: > Ok - we just looked into this - Ben: It looks like you're not ever creating RemoteElem which is why it's not getting registered. > > At the bottom of remote_elem.h you have this: > > extern const RemoteElem* remote_elem; > > But that's just creating a pointer. In the .C you have this: > > const RemoteElem* remote_elem; > > But, again, that's not creating a RemoteElem. > > In fact, nothing is ever creating a RemoteElem... so it doesn't get registered with the Singleton class. In remote_elem.C you could do this: > > extern const RemoteElem* remote_elem = new RemoteElem; That would be at risk of creating the RemoteElem before its underlying reference counter is set up, which is what got us here in the first place... in remote_elem.C, I am doing this: namespace { // Class to be dispatched by Singleton::setup() // to create the \p RemoteElem singleton. // While this actual object has file-level static // scope and will be initialized before main(), // importantly the setup() method will not be invoked // until after main(). class RemoteElemSetup : public Singleton::Setup { void setup () { RemoteElem::create(); } } remote_elem_setup; } the remote_elem_setup should get instantiated statically, and its *constructor* adds (this) tot the list of objects to be invoked by Singleton::setup(). In turn, that should call remote_elem_setup.setup() indirectly, and create the singleton. This is precisely the mechanism we described for singleton desctructors, now turned on its head. The only problem I can see is if the remote_elem_setup object is getting created before the container inside libmesh_singleton.C, resulting in undefined behavior. -Ben |