Memory management and directplay8
Who''s responsible for freeing allocated memory, direct play or myself?
For example, if I allocate a new message and then send it, I assume that I am in charge of freeing it. How/where do I do that? My guess is when you handle the DPN_MSGID_SEND_COMPLETE message.
Another example, if I receive a DPN_MSGID_RECEIVE message, how long is the pointer to the message (pMsgBuffer) valid? When does directplay free it or is that something I am supposed to do?
And what exactly do I need to wrap with a critical section? I am currently using a critical section around my player list but all the problems I am experiencing leads me to believe that I need to do more. Do I need to use a critical section throughout my entire game everywhere I use my player list or just in the directplay message handler?
Thanks in advance for your help. This game is due next week and the directplay documentation is frustratingly inadequate for someone like me who is trying to learn networking.
Each time you send a message with Send() or SentTo() Directplay will make a copy of your memory, unless you use the DPNSEND_NOCOPY flag. In case you use the nocopy flag you must delete the memory when you receive the send completed message.
The second question is slightly more complicated to explain...
Think of it like this way: When a normal program is running, you know that each line of your code will be taken in turn. Line 1 will always be executed before line 2 etc... Using global variables and such is no problem since you are only using them with one line at a time.
But! When you are using DirectPlay, or any other multi-threaded design (since DP always makes your game multi-threaded), this is not true any longer. While you think line 2 is executed, the game is perhaps suddenly executing line 1 again because of one of the other threads. In other words, a DP game has 2 threads: Your main game and the network thread. The main game is like normal, it will update as often as you like (probably checking for window messages once per loop). The network thread runs in the background is triggered as soon as you receive a packet, somebody is disconnected, somebody wants to join etc.. etc.. The problem here is that DP can be triggered at any time and doesn''t care much whether you are updating players, monsters or rendering polygons...
The worst case scenario could be like this:
Game thread: Start updating player 2
Network thread: Player 2 has disconnected
Network thread: Remove player 2 from the global list
Game thread: Compute physics for player 2
Game thread: Crashes "Access violation" (player 2 has been deleted)
Soooo... The solution to this is to lock important parts of the game with critical sections. A critical section should protect global variables that are accessed by both the game and the network thread. My example would then be:
Game thread: Enter critical section for players
Game thread: Start updating player 2
Network thread: Enter critical section for players fails! We must wait! Thread is locked.
Game thread: Compute physics for player 2
Game thread: Leave critical section for players.
Network thread: Player 2 has disconnected
Network thread: Remove player 2 from the global list
Network thread: Leave critical section for players.
I hope this helps![](smile.gif)
My Stuff : [ Whispers in Akarra (online rpg) || L33T WAR (multiplayer game) || The Asteroid Menace (another game) ]
The second question is slightly more complicated to explain...
Think of it like this way: When a normal program is running, you know that each line of your code will be taken in turn. Line 1 will always be executed before line 2 etc... Using global variables and such is no problem since you are only using them with one line at a time.
But! When you are using DirectPlay, or any other multi-threaded design (since DP always makes your game multi-threaded), this is not true any longer. While you think line 2 is executed, the game is perhaps suddenly executing line 1 again because of one of the other threads. In other words, a DP game has 2 threads: Your main game and the network thread. The main game is like normal, it will update as often as you like (probably checking for window messages once per loop). The network thread runs in the background is triggered as soon as you receive a packet, somebody is disconnected, somebody wants to join etc.. etc.. The problem here is that DP can be triggered at any time and doesn''t care much whether you are updating players, monsters or rendering polygons...
The worst case scenario could be like this:
Game thread: Start updating player 2
Network thread: Player 2 has disconnected
Network thread: Remove player 2 from the global list
Game thread: Compute physics for player 2
Game thread: Crashes "Access violation" (player 2 has been deleted)
Soooo... The solution to this is to lock important parts of the game with critical sections. A critical section should protect global variables that are accessed by both the game and the network thread. My example would then be:
Game thread: Enter critical section for players
Game thread: Start updating player 2
Network thread: Enter critical section for players fails! We must wait! Thread is locked.
Game thread: Compute physics for player 2
Game thread: Leave critical section for players.
Network thread: Player 2 has disconnected
Network thread: Remove player 2 from the global list
Network thread: Leave critical section for players.
I hope this helps
![](smile.gif)
My Stuff : [ Whispers in Akarra (online rpg) || L33T WAR (multiplayer game) || The Asteroid Menace (another game) ]
My Stuff : [ Whispers in Akarra (online rpg) || L33T WAR (multiplayer game) || The Asteroid Menace (another game) ]
To give you a better example, these are my critical sections in my online rpg:
cs_players
I enter this as soon as the world begins to update and doesn''t leave it again until all players have been updated. The network threads wants to enter this when a player receives a message (each player has their own list of waiting messages, and return DPNSUCCESS_PENDING until they have been procesed), when a player joins or when a player leaves.
cs_characterfiles
cs_accountfiles
These two are used to protect file reads and writes so that the two threads doesn''t attempt to modify the files at the same time.
cs_lbstrings
The server has an output window where I can see certain events in the game. These strings are placed in a list and outputted once for every main game loop, so this section makes sure that the list of strings only is used by one of the threads.
My Stuff : [ Whispers in Akarra (online rpg) || L33T WAR (multiplayer game) || The Asteroid Menace (another game) ]
cs_players
I enter this as soon as the world begins to update and doesn''t leave it again until all players have been updated. The network threads wants to enter this when a player receives a message (each player has their own list of waiting messages, and return DPNSUCCESS_PENDING until they have been procesed), when a player joins or when a player leaves.
cs_characterfiles
cs_accountfiles
These two are used to protect file reads and writes so that the two threads doesn''t attempt to modify the files at the same time.
cs_lbstrings
The server has an output window where I can see certain events in the game. These strings are placed in a list and outputted once for every main game loop, so this section makes sure that the list of strings only is used by one of the threads.
My Stuff : [ Whispers in Akarra (online rpg) || L33T WAR (multiplayer game) || The Asteroid Menace (another game) ]
My Stuff : [ Whispers in Akarra (online rpg) || L33T WAR (multiplayer game) || The Asteroid Menace (another game) ]
Thanks for the reply, that cleared up a lot. If you wrap such a large section of code where you update the physics, etc, doesn''t that make your message handler function block for a long time? That is something I''ve been really dilligent to try to avoid but at the same time, that approach made the most sense to me in terms of being thread safe.
Oh, one other question I need an answer to as well:
How long is the pointer to the message (pMsgBuffer) valid after I receive it? When does directplay free it or is that something I am supposed to do?
How long is the pointer to the message (pMsgBuffer) valid after I receive it? When does directplay free it or is that something I am supposed to do?
My server requires about 1% of my CPU power at the moment, so I don''t think it is blocked very long... Not sure how it would work with 1000 users, though ![](wink.gif)
DirectPlay holds on to your messages until you use IDirectPlayServer8::ReturnBuffer();
My Stuff : [ Whispers in Akarra (online rpg) || L33T WAR (multiplayer game) || The Asteroid Menace (another game) ]
![](wink.gif)
DirectPlay holds on to your messages until you use IDirectPlayServer8::ReturnBuffer();
My Stuff : [ Whispers in Akarra (online rpg) || L33T WAR (multiplayer game) || The Asteroid Menace (another game) ]
My Stuff : [ Whispers in Akarra (online rpg) || L33T WAR (multiplayer game) || The Asteroid Menace (another game) ]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement