|
|
|
|||||
|
LocalObject vs Object for "no-Ice" application?
I'll admit, for starters, that I'm not sure exactly what the pathology of this is, but I have a case where an application -- which uses Ice facilities, but not the communicator -- works if I inherit from LocalObject, but not if I inherit from Object.
Specifically, it seems that presence of a IceUtil::Handle hangs my test app -- in what I had previously believed was a totally unrelated place -- if the template parameter is of a class that derives from Ice::Object. I tried to narrow this down some more, but wasn't able to reproduce it with a trivial use of handles and threads (though I was able to trigger an assertion, as long as I wasn't running under the debugger). The sample in question is less than 200 lines, though, so I figure I'll throw it up here anyway. I'm running on Fedora Core 1 with all the latest glibc goodies. If you change Code:
class TimedEventService : virtual public Ice::LocalObject {
Code:
class TimedEventService : virtual public Ice::Object {
Mike |
|
|||||
|
Re: Re: LocalObject vs Object for "no-Ice" application?
Quote:
Quote:
Quote:
Mike |
|
||||||
|
Can you please also try running with the environment variable LD_ASSUME_KERNEL set to 2.4.1?
Code:
LD_ASSUME_KERNEL=2.4.1 export LD_ASSUME_KERNEL Cheers, Michi. |
|
|||||
|
Quote:
Mike |
|
||||||
|
OK, looks like it's related to threading or mutex semantics then. Hmmm... I don't have a Fedora system available (I guess this is something we need to address...), so I can't track this down. If you can find the time, it would be great to get some more info. Single-stepping with a debugger might help to get you to the point where the hang happens. Once we know which mutex (I'm pretty sure the hang happens on a mutex lock) is responsible, I should be able to figure out what is happening.
Cheers, Michi. |
|
||||||
|
Re: Re: Re: LocalObject vs Object for "no-Ice" application?
Hi Mike,
Quote:
First, the IceUtil::Handle template technically doesn't require Ice::Object, it's just that Ice::Object implements the interface that IceUtil::Handle expects. If you want to use IceUtil::Handle in your code without using Ice classes, you can derive your class from IceUtil::Shared or IceUtil::SimpleShared. Second, we don't really recommend manually deriving a class from Ice::Object. This should generally be left to the Slice compiler. Finally, I too built your example and it worked as Michi described. Admittedly, I was using RH9 and our development sources. Good luck, - Mark |
|
||||||
|
Hi Mike,
thanks for providing me with the account on your machine to work this out. I think I have identified the problem. In your code, the destructor of evsvc is called by the main thread at the end of the nested block in main(). Because evscv is a Handle to a TimedEventService, and TimedEventService is derived from Ice::Object, this causes a call to __decRef() on the IceUtil::GCShared base, which calls delete because the reference count of the object has now dropped to zero. The call to delete is made with a lock held on gcRecMutex. In turn, the call to delete results in a call to ~TimedEventService() which tries to join with the thread spawned previously. Meanwhile, the spawned thread is in its run() method and has just been woken up from its call to wait(). _stopping is now true and run() returns, which results in the destruction of the local variable nowEvent. nowEvent is a handle to a TimedEventService, which is derived from Ice::Object, and the destructor results in a call to the IceUtil::GCShared base as well. As a result, the thread about to terminate is trying to acquire the same lock that is currently held by the main thread in the destructor of TimedEventService. The spawned thread can't terminate until the lock is unlocked, but the main thread holds the same lock while it calls join(), so we get a deadlock. Looking at the code, the problem appears to be in IceUtil::GCShared::__decRef(). The last few lines read: Code:
if(doDelete)
{
delete this;
}
gcRecMutex._m->unlock();
Code:
gcRecMutex._m->unlock();
if(doDelete)
{
delete this;
}
Could you please rebuild Ice with the above change (in src/IceUtil/GCShared.cpp) and try again? Thanks, Michi. |
|
||||||
|
Yes, doesn't surprise me. Unfortunately, on further examination, making this change opens up another potential race condition with the garbage collector, so it's not really a fix. I need to think about this a bit more -- I'll post a proper fix in the next few days.
Cheers, Michi. |
![]() |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Don't "Ice-3.1.1-VC71.msi " include the "slice2java.exe"? | Jason Gao | Help Center | 4 | 10-26-2006 11:23 AM |
| Icepack registry "TimeOut" exception with heavy load | eaglecn | Help Center | 1 | 05-26-2006 12:02 AM |
| "Invalid UTF8 string" when transer chinese chars between cpp server and csharp client | raygo | Help Center | 8 | 03-21-2006 08:34 PM |
| IceGrid startup performance and CPU usage "problem" | kovacm | Comments | 11 | 12-06-2005 06:52 AM |
| Going from "in" to "out" param, using a class as a union | catalin | Help Center | 1 | 04-05-2004 08:55 AM |