Jump to content

  • Log In with Google      Sign In   
  • Create Account


Mussi

Member Since 12 Oct 2004
Offline Last Active Today, 07:19 AM

Topics I've Started

Promise and Future with shared_ptr safety

27 August 2013 - 11:31 AM

Hey everyone,

 

I've implemented sort of future and promise classes for my network code using a shared_ptr that holds a boolean and a value variable. These variables are set by the promise class, which is non-copyable. The future class only reads from these variables. I thought that it'd be safe to set the boolean from within the promise in thread A and concurrently read the boolean value from within the future in thread B, but apparently it's not. What happens is that sometimes the value is not set when repeatedly reading the boolean value, even though the code is called and the address of booleans match. My question is, why is this not safe and what's happening?

 

The code:

class Future
	{
		friend class Promise;

	private:
		struct FutureData
		{
			NetworkResult value;
			bool ready;

			FutureData() : ready(false) {}
		};

		std::shared_ptr<FutureData> data;

	public:
		Future()
		{
			data = std::make_shared<FutureData>();
		}

		Future(const Future& future) : data(future.data)
		{
		}

		Future& operator =(const Future& future)
		{
			data = future.data;
		}

		Future(Future&& future) : data(std::move(future.data))
		{
		}

		Future& operator =(const Future&& future)
		{
			data = std::move(future.data);
			return *this;
		}

		bool IsReady() const
		{
			return data->ready;
		}

		NetworkResult GetValue() const
		{
			return data->value;
		}
	};

	class Promise
	{
	private:
		Future future;

		Promise(const Promise&);
		Promise& operator =(const Promise&);

	public:
		Promise()
		{	
		}

		Promise(Promise&& promise) : future(std::move(promise.future))
		{
		}

		Promise& operator =(Promise&& promise)
		{
			future = std::move(promise.future);
			return *this;
		}

		Future GetFuture() const
		{
			return future;
		}

		void SetValue(NetworkResult result)
		{
			future.data->value = result;
			future.data->ready = true;
		}
	};

Any help is very much appreciated.


Daily Newsletter

19 June 2013 - 12:22 PM

What's with this daily newsletter thing? I got three of them now and they mostly contain duplicate info. Even if every newsletter would contain completely new information, I wouldn't want to receive them on a daily basis.

 

What's the reasoning behind this and what do the rest of you think about this?


IOTD not as popular?

04 December 2012 - 10:58 PM

Hey guys and galls,

Is it just me or is the IOTD section less commented on since the big site revamp? It feels like there used to be a lot more participants in the comment sections. Any of you feel the same? If this is actually the case, what happened?

Also, the IOTD is not accessible from the menu :(

Connection layer design

28 August 2012 - 06:20 AM

Hey everyone,

I'm looking at some old networking code that I wrote some time ago and I'm looking for a way to improve it and change the design. I enjoy doing this, so that's my motive.

This is all written in C++ and on top of BSD sockets and the goal was to create a connection layer on top of UDP. I'll first show how I achieved this goal previously and point out what I don't like about it and then continue with the ideas that have been running through my mind but seem to fall short.

So currently I have a socket class that's very similar to the one used in Glenn Fielder's Networking for Game Programmers articles, which is basically a class wrapped around the BSD functions.
Managing which packets should go where is done by a class called Tranceiver(<insert oh god why meme>). This class owns a Socket object used to send and receive packets. Connections can be registered here to listen for a specific or any address, once a connection has been setup the Transceiver class passes the packets on to the corresponding connection.
The connection class is responsible for setting up connections, keeping them alive with keep alive packets, detecting disconnects and passing on the packet data(packet minus the header) to some handler and forms the gateway between the two ends to send data across. This class holds a reference to the Tranceiver it's associated with and next to sending packets, it's used to register/de-register on connects/disconnects.

It's that last part that I dislike the most. I don't like de dependency of the two classes on each other and it should be possible to set up a connection with just a socket, since a client that's only connected to a server shouldn't need a manager.

The solution seems simple, have the connection class hold a reference to a socket instead, but now not only do you need to make sure the connection you're registering to a manager uses the same socket but you'll have to manually register/de-register connections.
Another option is to have the connection manager create connections with the appropriate socket and not allow external connections to be registered. Still have to manually register/de-register connections and re-registering becomes confusing, do I destroy and recreate a connection? Calling a method to re-register a connection, accepting a connection as an argument seems weird since only connections created by the manager should be accepted.

What design can I use to make it more consistent, have less dependency and avoid manual registration? Any help or feedback is welcome.

IOTD comment bug?

21 July 2012 - 06:39 AM

Hi,

Got this error message while commenting on this IOTD:
[source lang="bash"]Warning: Data missing in classes_like_composite::add in /var/www/gamedev/admin/sources/classes/like/composite.php on line 477Warning: Relationship ID missing in classes_like_registry::getKey in /var/www/gamedev/admin/sources/classes/like/composite.php on line 143[/source]
Before I started commenting the comment count was 1 but I didn't see an actual comment, after commenting it increased to 2 but neither are visible.

I'm using Firefox 14.0.1 if that's of any help.

PARTNERS