Is it safe if I want to call closesocket() on a server socket from 1 thread which is separate from another thread which runs the server using the same server socket?
The call itself is thread-safe, but the practice is not. Whenever you're deallocating a resource whose identifier could be reused after it's deallocated, you must synchronize with all threads that could possibly use it. Otherwise, it's possible that, after the resource is deallocated, a new resource (in your case, socket) could be allocated with the same identifier (socket number), and code intending to access the (now closed) server socket could end up operating on a different socket.
The degree to which this is dangerous (and whether it can happen at all) depends a lot on your code. It might not happen if you never create any more sockets after closing the server socket. But it's still conceptually very wrong, and anyone competent reviewing your code would consider this very bad.
Edit: The solution to problems like this is protection of the resource descriptor (not the resource itself) with a reader-writer lock (rwlock). Accessing the resource descriptor (the integer variable holding the socket number, in your case) requires holding a "read" lock on it, whether you'll be performing input or output or other operating using the resource it refers to. Deallocating the resource (and storing a sentinel value like -1 in the variable holding the descriptor) requires a write lock.
Yes, it's not a problem. Naturally, there will be exceptions/errors generated in the other thread/s that have calls outstanding on the socket, but the network stack itself, (which has to be thread-safe because of all the different processes/threads that are normally using it), will not be damaged.
Related
The title pretty much says it all. I'm new to Winsock, and I need to know what the scope of a SOCKET object is.
Do I need to worry about it going out of scope when using it in a class member variable (since when it's returned, it's not dynamic memory)?
Thanks.
I'm pretty sure the answer to this is no, but since I can't find the info, I figured I would put it out there, for quick reference to others in the future.
The MSDN documentation for socket says the following:
When a session has been completed, a closesocket must be performed.
And the accompanying sample does just that. The documentation for closesocket is more forceful:
An application should always have a matching call to closesocket for each successful call to socket to return any socket resources to the system.
So as long as you keep the SOCKET descriptor somewhere you can use it until you call closesocket. You could consider putting it inside your own RAII type (or use an existing one) to avoid leaks. If you "forget" the descriptor, you will leak the internal resources.
Internally, SOCKET is just some ID, which is refers to some internal Windows structure. You can work with it like with HANDLE or with usual pointer.
I.e. nothing will happen, if it will go out of scope (but it can leak resources, like HANDLE, if you forgot CloseHandle), if you copy it - you will go 2 same sockets, which are referring to same Windows structure, etc.
I'm writing some asio/tcp server and would like to map native socket descriptor with tcp session identifier.
I'm writing id getter like:
inline int get_session_id() { return socket_.native_handle(); }
And calling from second (packets dispatching thread) thread like:
cout << session_shared_ptr->get_session_id() << endl;
and it writes valid id only for first time, so I guess to something in my implementation is bad.
Can anyone advice me where I did mistake?
Firstly, using the native handle as a session id strikes me as a fantasticically bad idea.
Not only did you pick an implementation defined backdoor, but also you picked one that is not portable - so your code risks getting different semantics across platforms.
Remember, these are the underlying handles of an abstraction. The abstractions exist for a reason! Who knows, if your network gets reconnected the native handle may change. Nowhere is it documented that you can retain the handle and rely on it to identify the API object.
Of course when you do multi threading, you have to keep in mind everything you always do when threading:
synchronize access to shared state and resources
coordinate the lifetime of such objects
guard against starvation and dead/soft locks while doing the above
Now, you don't speak about synchronization measures, so you have a data race:
Thread Safety
Distinct objects: Safe.
Shared objects: Unsafe.
The standard specifies a data race as Undefined Behaviour; Anything can happen. You can be thankful your house didn't burn down. Yet.
All in all: just use a dependable ID. Generate a UUID and store it in the session. Use the C++ object identity (i.e. address) for identification if you know you don't move sessions with equality.
If you must for some useful reason access the socket from another thread, provide synchronization (mutex - mutual exclusion, or by way of posting to the session strand).
Using boost::asio i use async_accept to accept connections. This works good, but there is one issue and i need a suggestion how to deal with it. Using typical async_accept:
Listener::Listener(int port)
: acceptor(io, ip::tcp::endpoint(ip::tcp::v4(), port))
, socket(io) {
start_accept();
}
void Listener::start_accept() {
Request *r = new Request(io);
acceptor.async_accept(r->socket(),
boost::bind(&Listener::handle_accept, this, r, placeholders::error));
}
Works fine but there is a issue: Request object is created with plain new so it can memory "leak". Not really a leak, it leaks only at program stop, but i want to make valgrind happy.
Sure there is an option: i can replace it with shared_ptr, and pass it to every event handler. This will work until program stop, when asio io_service is stopping, all objects will be destroyed and Request will be free'd. But this way i always must have an active asio event for Request, or it will be destroyed! I think its direct way to crash so i dont like this variant, too.
UPD Third variant: Listener holds list of shared_ptr to active connections. Looks great and i prefer to use this unless some better way will be found. The drawback is: since this schema allows to do "garbage collection" on idle connects, its not safe: removing connection pointer from Listener will immediately destroy it, what can lead to segfault when some of connection's handler is active in other thread. Using mutex cant fix this cus in this case we must lock nearly anything.
Is there a way to make acceptor work with connection management some beautiful and safe way? I will be glad to hear any suggestions.
The typical recipe for avoiding memory leaks when using this library is using a shared_ptr, the io_service documentation specifically mentions this
Remarks
The destruction sequence described above permits programs to simplify
their resource management by using shared_ptr<>. Where an object's
lifetime is tied to the lifetime of a connection (or some other
sequence of asynchronous operations), a shared_ptr to the object would
be bound into the handlers for all asynchronous operations associated
with it. This works as follows:
When a single connection ends, all associated asynchronous operations
complete. The corresponding handler objects are destroyed, and all
shared_ptr references to the objects are destroyed. To shut down the
whole program, the io_service function stop() is called to terminate
any run() calls as soon as possible. The io_service destructor defined
above destroys all handlers, causing all shared_ptr references to all
connection objects to be destroyed.
For your scenario, change your Listener::handle_accept() method to take a boost::shared_ptr<Request> parameter. Your second concern
removing connection pointer from Listener will immediately destroy it,
what can lead to segfault when some of connection's handler is active
in other thread. Using mutex cant fix this cus in this case we must
lock nearly anything.
is mitigated by inheriting from the boost::enable_shared_from_this template in your classes:
class Listener : public boost::enable_shared_from_this<Listener>
{
...
};
then when you dispatch handlers, use shared_from_this() instead of this when binding to member functions of Listener.
If anyone interested, i found another way. Listener holds list of shared_ptr to active connections. Connections ending/terminating is made via io_service::post which call Listener::FinishConnection wrapped with asio::strand. Usually i always wrap Request's methods with strand - its safer in terms of DDOS and/or thread safety. So, calling FinishConnection from post using strand protects from segfault in other thread
Not sure whether this is directly related to your issue, but I was also having similar memory leaks by using the Boost Asio libraries, in particular the same acceptor object you mentioned. Turned out that I was not shutting down the service correctly; some connections would stay opened and their corresponding objects would not be freed from memory. Calling the following got rid of the leaks reported by Valgrind:
acceptor.close();
Hope this can be useful for someone!
Recently I heard that memory in the stack is not shared with other thread and memory in the heap is shared with other threads.
I normally do:
HWND otherThreadHwnd;
DWORD commandId;
// initialize commandId and otherThreadHwnd
struct MyData {
int data1_;
long data2_;
void* chunk_;
};
int abc() {
MyData myData;
// initialize myData
SendMessage(otherThreadHwnd,commandId,&myData);
// read myData
}
Is it alright to do this?
Yes, it is safe in this instance.
Data on the stack only exists for the lifetime of the function call. Since SendMessage is a synchronous, blocking call, the data will be valid for the duration of that call.
This code would be broken if you replace SendMessage with a call to PostMessage, SendNotifyMessage, or SendMessageCallback, since they would not block and the function may have returned before the target window received the message.
I think 2 different issues are being confused by whoever you "heard that memory in the stack is not shared with other thread":
object lifetime - the data on the stack is only valid as long the thread doesn't leave the scope of the variable's name. In the example you giove, you're handling this by making the call to the other thread synchronously.
memory address visibility - the addresses pspace for a process is shared among the various threads in that process. So variables addressable by one thread are addressable by other threads in that process. If you are passing the address to a thread in a different process, the situation is quite different and you'd need to use some other mechanism (which might be to ensure that the memory block is mapped into both processes - but that I don't think that can normally be done with stack memory).
Yes, it is okay.
SendMessage is working in blocking mode. Even if myData is allocated in stack, its address is still visible to all threads in the process. Each thread has its own private stack; but data in the stack can be explicitly shared, for example, by your code. However, as you guess, do not use PostThreadMessage in such case.
What you heard about is "potential infringement of privacy", which is sharing the data on one thread's private stack with another thread.
Although it is not encouraged, it is only a "potential" problem--with correct synchronization, it can be done safely. In your case, this synchronization is done by ::SendMessage(); it will not return until the message is processed in the other thread, so the data will not go out of scope on the main thread's stack. But beware that whatever you do with this pointer in the worker thread, it must be done before returning from the message handler (if you're storing it somewhere, be sure to make a copy).
As others have said already, how you have it written is just fine, and in general, nothing will immediately fail when passing a pointer to an object on the stack to another thread as long as everything's synchronized. However, I tend to cringe a little when doing so because things that seem threadsafe can get out of their intended order when an exception occurs or if one of the threads is involved with asynchronous IO callbacks. In the case of an exception in the other thread during your call to SendMessage, it may return 0 immediately. If the exception is later handled in the other thread, you may have an access violation. Yet another potential hazard is that whatever's being stored on the stack can never be forcibly disposed of from another thread. If it gets stuck waiting for some callback, object, etc, forever and the user has decided to cancel or quit the application, there is no way for the working thread to be sure the stalled thread has tidied up whatever objects are on its stack.
My point is this: In simple scenarios as you've described where everything works perfectly, nothing ever changes, and no outside dependencies fail, sharing pointers to the local stack is safe - but since allocating on the heap is really just as simple, and it gives you the opportunity to explicitly control the object's lifetime from any thread in extenuating circumstances, why not just use the heap?
Finally, I strongly suggest that you be very careful with the void* chunk_ member of your MyData structure, as it is not threadsafe as described if it's copied in the other thread.
I have an object (Client * client) which starts multiple threads to handle various tasks (such as processing incoming data). The threads are started like this:
// Start the thread that will process incoming messages and stuff them into the appropriate queues.
mReceiveMessageThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)receiveRtpMessageFunction, this, 0, 0);
These threads all have references back to the initial object, like so:
// Thread initialization function for receiving RTP messages from a newly connected client.
static int WINAPI receiveRtpMessageFunction(LPVOID lpClient)
{
LOG_METHOD("receiveRtpMessageFunction");
Client * client = (Client *)lpClient;
while(client ->isConnected())
{
if(client ->receiveMessage() == ERROR)
{
Log::log("receiveRtpMessageFunction Failed to receive message");
}
}
return SUCCESS;
}
Periodically, the Client object gets deleted (for various good and sufficient reasons). But when that happens, the processing threads that still have references to the (now deleted) object throw exceptions of one sort or another when trying to access member functions on that object.
So I'm sure that there's a standard way to handle this situation, but I haven't been able to figure out a clean approach. I don't want to just terminate the thread, as that doesn't allow for cleaning up resources. I can't set a property on the object, as it's precisely properties on the object that become inaccessible.
Thoughts on the best way to handle this?
I would solve this problem by introducing a reference count to your object. The worker thread would hold a reference and so would the creator of the object. Instead of using delete, you decrement from the reference count and whoever drops the last reference is the one that actually calls delete.
You can use existing reference counting mechanisms (shared_ptr etc.), or you can roll your own with the Win32 APIs InterlockedIncrement() and InterlockedDecrement() or similar (maybe the reference count is a volatile DWORD starting out at 1...).
The only other thing that's missing is that when the main thread releases its reference, it should signal to the worker thread to drop its own reference. One way you can do this is by an event; you can rewrite the worker thread's loop as calls to WaitForMultipleObjects(), and when a certain event is signalled, you take that to mean that the worker thread should clean up and drop the reference.
You don't have much leeway because of the running threads.
No combination of shared_ptr + weak_ptr may save you... you may call a method on the object when it's valid and then order its destruction (using only shared_ptr would).
The only thing I can imagine is to first terminate the various processes and then destroy the object. This way you ensure that each process terminate gracefully, cleaning up its own mess if necessary (and it might need the object to do that).
This means that you cannot delete the object out of hand, since you must first resynchronize with those who use it, and that you need some event handling for the synchronization part (since you basically want to tell the threads to stop, and not wait indefinitely for them).
I leave the synchronization part to you, there are many alternatives (events, flags, etc...) and we don't have enough data.
You can deal with the actual cleanup from either the destructor itself or by overloading the various delete operations, whichever suits you.
You'll need to have some other state object the threads can check to verify that the "client" is still valid.
One option is to encapsulate your client reference inside some other object that remains persistent, and provide a reference to that object from your threads.
You could use the observer pattern with proxy objects for the client in the threads. The proxies act like smart pointers, forwarding access to the real client. When you create them, they register themselves with the client, so that it can invalidate them from its destructor. Once they're invalidated, they stop forwarding and just return errors.
This could be handled by passing a (boost) weak pointer to the threads.