Author Topic: Problem with using GNE from a .dll?  (Read 8388 times)

CowboyCoder

  • User
  • *
  • Posts: 5
    • http://delta3d.org
Problem with using GNE from a .dll?
« on: September 15, 2005, 01:00:54 PM »
We are investigating using GNE for our Open Source game engine (http://delta3d.org), but are having some troubles getting a clean startup/shutdown sequence.

After much troubleshooting, it appears that the EventGenerator isn't stopping during the shutdownGNE(), which causes a:
"CEG failed to shut down properly!  Please file a bug report."

This only happens on the server side after a client connects, then disconnects.

I'm wondering if there is an issue with using GNE from inside a .dll?  I say that because if I call GNE stuff from the main(), I get different results from calling GNE stuff from the .dll.

Any initial thoughts?
-XP
-MSVC 7.1
-HawkNL 1.7 beta 1
-GNE 0.70
-Boost 1.32

Thanks!

Gillius

  • Administrator
  • User
  • *****
  • Posts: 147
    • http://www.gillius.org/
Problem with using GNE from a .dll?
« Reply #1 on: September 15, 2005, 11:49:19 PM »
I'm surprised that you were able to use GNE from a DLL environment at all.  I've tried exploring the issues for this in the past but I never had much knowledge in DLL, and I knew that GNE in a DLL would be pointless since DLLs in C++ are never portable even between different versions of the same compiler, and sharing things like objects from the STL and templates is extremely difficult or impossible.  When you cross DLL boundaries, there are both problems because of potentially different heaps, but also potentially different standard libraries and also versioning problems with templates, since they are instantiated at the caller side and not exported as code.

I've tried some cursory efforts at one day allowing GNE to be in a DLL, like support for custom memory allocators, but I'm sure there are still other issues.

If there is a chance the GNE will work in or from a DLL, all code will need to be compiled with the same compiler, and with the same runtime library (in MSVC case, you must use multithreaded DLL runtime for everything).

Because your only problem is the CEG not shutting down, I'm figuring that pointer and heap problems are not an issue here, but I figured I'd state the above just in case.  I've heard of another report of the CEG not shutting down (in Linux) and I looked into it but I can't see how it could be possible, but I did find out recently that _REENTRANT needs to be defined on UNIX so that could be the problem there and perhaps unrelated to yours.

Honestly, I work full-time now and I'm also taking 2 night classes towards a graudate degree so I have almost literally zero time to spend on GNE for quite some time.  You may have better luck using the CVS version which has quite a few bug fixes.  I've been wanting to release a new version from CVS for awhile but haven't had the time to properly test and package it yet.

Ultimately, if the CEG fails to shutdown this is not a huge issue.  The CEG does not hold any resources that it needs to free except for a small amount of memory including the Thread object that it runs from.  If the CEG does not stop, this does not prevent normal program shutdown as when main() ends, the program will stop whether the CEG has or not.  The operating system should clean up properly after this event.

If you want to help in debugging this, what I would really need is a stack trace of the CEG thread when it shuts down.  IF this happens to you every time, or you can reproduce it, then set a breakpoint in the shutdownGNE function and where the request to shutdown CEG is made, then get a stack trace for all of the threads -- maybe there is a deadlock.

EDIT: BTW: I am very flattered that you are considering GNE for use in the Delta3D library -- I just wish that the library was in a better condition or that I had time to support and develop it more.
Gillius
Gillius's Programming http://www.gillius.org/

CowboyCoder

  • User
  • *
  • Posts: 5
    • http://delta3d.org
Problem with using GNE from a .dll?
« Reply #2 on: September 16, 2005, 01:07:34 PM »
Yes, we've been dealing with the .dll issues for some time now.  We do try to follow all the rules: same compiler, same runtime library, etc.  

We seem to be close to getting this to work, just trying to flush out some last items.  I went back to the HawkNL 1.68 version and doing so appears to have changed the results.  I don't think the CEG is hanging up on exit now, but now I'm having troubles reconnecting a client who just disconnected.  I'll look more into this and report back!

I'll also give the CVS version of GNE a try.

Thanks for the lengthy reply!

(If we choose to go with GNE, you might find yourself getting all kinds of help with development, not only from the Delta3D team, but from our users.  Could be a wild ride!)

Gillius

  • Administrator
  • User
  • *****
  • Posts: 147
    • http://www.gillius.org/
Problem with using GNE from a .dll?
« Reply #3 on: September 16, 2005, 06:09:19 PM »
I would welcome the help -- but unfortuantely now that I am taking more classes, I wish that I had time to coordinate it.  If GNE was selected, and help did start to arrive, it may be difficult for me to keep up adminstrating it, but the benefits would be high for the library and I will try while possible.
Gillius
Gillius's Programming http://www.gillius.org/

CowboyCoder

  • User
  • *
  • Posts: 5
    • http://delta3d.org
Problem with using GNE from a .dll?
« Reply #4 on: September 22, 2005, 01:31:11 PM »
For what it's worth, we ended up compiling everything as a static lib: HawkNL, GNE, and our library that uses GNE.

I ran into all kinds of interesting problems trying to use GNE from a .dll.  Once everything was in a static lib, these problems went away.

I'm still having some problems with getting a good, clean shutdown sequence, but I'm hoping thats just a "user error" on my part.

Is there any guidance on the steps required to a client/server to disconnect from the network?

Gillius

  • Administrator
  • User
  • *****
  • Posts: 147
    • http://www.gillius.org/
Problem with using GNE from a .dll?
« Reply #5 on: September 22, 2005, 02:03:53 PM »
As I said, I can't see what the problem is, but I've been hearing people complaining about problems that the CEG is not shutting down, so there could be a bug in GNE somewhere here (if that's what you mean by a clean shutdown sequence).

All that is needed to shutdown GNE is to call the shutdownGNE function.  This should close all connections and request all threads to shutdown (and wait for their termination for up to a configurable time limit with a default of I think 10 seconds).

Memory leak can occur if you cause cycles with the smart pointers.  Specifically, holding a smart pointer to a Connection from a ConnectionListener listening to that Connection is not allowed (the API is designed so that you never need to do this, so if you need it for some reason let's discuss).

So the question is more about your exact problems with shutdown now -- what do you call a "clean" shutdown?  You asked specifically how to disconnect: all you need to do is to just call disconnect and you should be fine; I'm not sure what else to say here.
Gillius
Gillius's Programming http://www.gillius.org/

CowboyCoder

  • User
  • *
  • Posts: 5
    • http://delta3d.org
Problem with using GNE from a .dll?
« Reply #6 on: September 22, 2005, 02:14:09 PM »
What I meant was, if I'm playing a game and I hit the "disconnect" button, what sequence of events should the code do?

Should I just call shutdownGNE() from the client?  Or should I do something more interesting like calling disconnectSendAll() from the Connection?

Should I send out a "I'm disconnecting" packet and tell the network I'm leaving the game?

I'm just looking for the most gracefull way to disconnect a client (or server) from the network.  (not just from a GNE point of view, but also from a network game point of view)

Gillius

  • Administrator
  • User
  • *****
  • Posts: 147
    • http://www.gillius.org/
Problem with using GNE from a .dll?
« Reply #7 on: September 22, 2005, 05:37:23 PM »
Oh, I see.  Well you should call disconnectSendAll in the ideal situtation so that any packets that you've written but that haven't gotten sent yet will be sent.

You don't need to send a packet to the server to tell it that you are leaving, as GNE on a graceful shutdown does do that.  The onExit method in ConnectionListener is called when disconnect or disconnectSendAll is called on the remote side and it was able to successfully send an exiting packet.  Before onDisconnect is called in your listener, onExit or onFailure should be called if you did not call disconnect from the remote side.

I know that the prose sounds a little confusing (I was having a hard time even wording it well), so I will summarize in the form of a list:

[list=1]
  • Client code calls disconnectSendAll()
  • Client: GNE sends all pending packets
  • Client: GNE sends an exit packet
  • Client: invokes onDisconnect
  • Server: gets remaining client packets
  • Server: invokes onExit (graceful disconnect event)
  • Server: invokes onDisconnect
  • [/list:o]
Gillius
Gillius's Programming http://www.gillius.org/

CowboyCoder

  • User
  • *
  • Posts: 5
    • http://delta3d.org
Problem with using GNE from a .dll?
« Reply #8 on: September 22, 2005, 05:50:24 PM »
Ok cool.  I think that's what I'm doing. :)

Thanks for the informative reply!