Does DuplicateHandle() do any interprocess communication (IPC) and if not why target params? - c++

I am finding DuplicateHandle() very confusing. The third and fourth params, hTargetProcessHandle and lpTargetHandle seem to imply that this API function does some form of interprocess communication, but what I have been reading online seems to imply (without saying directly) that in fact this function cannot communicate with anything outside of the address space of its own process and that if you really do want to say copy the local process handle to another process you have to do that yourself manually.
So can someone please please take pity on me and tell me definitively whether or not this function does any IPC itself? Also if it doesn't do any IPC then what is the point of those two parameters? How can there be a 'target' if no data is sent and the output of this function is not visible to other processes?
At first I thought I could call GetCurrentProcess() and then use DuplicateHandle() to copy the local process handle to another process, but then I started to realize that it probably isn't that easy.

The third parameter hTargetProcessHandle is documented as
A handle to the process that is to receive the duplicated handle.
That means that the handle (which is just a numeric value underneath) will become usable within the target process. However, how you get this handle into the target process and in what context it is to be used there is out of the scope of that function. Also note that "is to receive" points in the future and it refers to the result of the call, so it must be after the call has finished.
As an analogy, you want to allow a friend in your house. For that, you are creating a second key to your door. Just that doesn't mean that your friend can now unlock your door, because you first have to give it to them, but it's a first step.

Related

what is the point of inherited handles without interprocess communication (ipc)?

From what I have been reading it appears that handle inheritance does not do any interprocess communication even between parent and child. Is this true? So you still have to figure out some way of getting the value of the handle from the parent to the child process such as by passing it as the second parameter in CreateProcess() or passing it as a named shared object. If so I am trying to understand what the point of it is.
It doesn't save you the extra step of doing ipc. Saying that the child has in any way 'inherited' the handle seems deceptive to me. What has it inherited? Is it not possible to create a handle with the parent process and just pass it as the second parameter in a call to CreateProcess() anyway? Without using so called 'inheritance'?
To clarify, process A calls CreateProcess() to start process B. I thought that B would gain some benefit in terms of easier ipc by being a child of A, but I have been disappointed. It seems that in order to actually use a so called inherited handle I still have to pass it for instance as a parameter to CreateProcess. Like CreateProcess("myprog.exe", myhandle,...), but it seems like I could just pass myhandle there anyway even without inheritance. I am trying to figure out what the point of it is.

What is the scope of a SOCKET object in Winsock?

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.

What is the difference between a blocking and non-blocking read?

Add to the above question the concept of a wait/no wait indicator as a parameter to a ReadMessage function in a TCP/IP or UDP environment.
A third party function description states that:
This function is used to read a message from a queue which was defined by a previous registerforinput call. The input wait/no wait indicator will determine if this function will block on the queue specified, waiting for the data to be placed on the queue. If the nowait option is specified and no data is available a NULL pointer will be returned to the caller. When data available this function will return a pointer to the data read from the queue.
What does it mean for a function to be blocking or non-blocking?
Blocking means that execution of your code (in that thread) will stop for the duration of the call. Essentially, the function call will not return until the blocking operation is complete.
A blocking read will wait until there is data available (or a timeout, if any, expires), and then returns from the function call. A non-blocking read will (or at least should) always return immediately, but it might not return any data, if none is available at the moment.
An analogy if you'll permit me - sorry, it's late in the afternoon and I'm in the mood, if it gets down voted - ah well...
You want to get into a snazzy nightclub, but the bouncer tells you you cannot go in till someone comes out. You are effectively "blocked" on that condition. When someone comes out, you are free to go in - or some error condition such as "are those trainers?" Your night doesn't really kick off till you get in, your enjoyment is "blocked".
In a "non-blocking" scenario, you will tell the bouncer your phone number, and he will call you back when there is a free slot. So now you can do something else while waiting for someone to come out, you can start your night somewhere else and come back when called and continue there...
Sorry if that didn't help...
Take a look at this: http://www.scottklement.com/rpg/socktut/nonblocking.html
Here's some excerpts from it:
'By default, TCP sockets are in "blocking" mode. For example, when you call recv() to read from a stream, control isn't returned to your program until at least one byte of data is read from the remote site. This process of waiting for data to appear is referred to as "blocking".'
'Its possible to set a descriptor so that it is placed in "non-blocking" mode. When placed in non-blocking mode, you never wait for an operation to complete. This is an invaluable tool if you need to switch between many different connected sockets, and want to ensure that none of them cause the program to "lock up."'
Also, it's generally a good idea to try to search for an answer first (just type "blocking vs. non-blocking read" in a search engine), and then once you hit a wall there to come and ask questions that you couldn't find an answer to. The link I shared above was the second search result. Take a look at this great essay on what to do before asking questions on internet forums: http://www.catb.org/~esr/faqs/smart-questions.html#before
In your case, it means the function will not return until there actually is a message to return. It'll prevent your program from moving forward, but when it does move forward you'll have a message to work with.
If you specify nowait, a null pointer will be returned immediately if there are no messages on the queue, which allows you to process that situation.

pthread_key_t and pthread_once_t?

Starting with pthreads, I cannot understand what is the business with pthread_key_t and pthread_once_t?
Would someone explain in simple terms with examples, if possible?
thanks
pthread_key_t is for creating thread thread-local storage: each thread gets its own copy of a data variable, instead of all threads sharing a global (or function-static, class-static) variable. The TLS is indexed by a key. See pthread_getspecific et al for more details.
pthread_once_t is a control for executing a function only once with pthread_once. Suppose you have to call an initialization routine, but you must only call that routine once. Furthermore, the point at which you must call it is after you've already started up multiple threads. One way to do this would be to use pthread_once(), which guarantees that your routine will only be called once, no matter how many threads try to call it at once, so long as you use the same control variable in each call. It's often easier to use pthread_once() than it is to use other alternatives.
No, it can't be explained in layman terms. Laymen cannot successfully program with pthreads in C++. It takes a specialist known as a "computer programmer" :-)
pthread_once_t is a little bit of storage which pthread_once must access in order to ensure that it does what it says on the tin. Each once control will allow an init routine to be called once, and once only, no matter how many times it is called from how many threads, possibly concurrently. Normally you use a different once control for each object you're planning to initialise on demand in a thread-safe way. You can think of it in effect as an integer which is accessed atomically as a flag whether a thread has been selected to do the init. But since pthread_once is blocking, I guess there's allowed to be a bit more to it than that if the implementation can cram in a synchronisation primitive too (the only time I ever implemented pthread_once, I couldn't, so the once control took any of 3 states (start, initialising, finished). But then I couldn't change the kernel. Unusual situation).
pthread_key_t is like an index for accessing thread-local storage. You can think of each thread as having a map from keys to values. When you add a new entry to TLS, pthread_key_create chooses a key for it and writes that key into the location you specify. You then use that key from any thread, whenever you want to set or retrieve the value of that TLS item for the current thread. The reason TLS gives you a key instead of letting you choose one, is so that unrelated libraries can use TLS, without having to co-operate to avoid both using the same value and trashing each others' TLS data. The pthread library might for example keep a global counter, and assign key 0 for the first time pthread_key_create is called, 1 for the second, and so on.
Wow, the other answers here are way too verbose.
pthread_once_t stores state for pthread_once(). Calling pthread_once(&s, fn) calls fn and sets the value pointed to by s to record the fact it has been executed. All subsequent calls to pthread_once() are noops. The name should become obvious now.
pthread_once_t should be initialized to PTHREAD_ONCE_INIT.

Is it possible to use function pointers across processes?

I'm aware that each process creates it's own memory address space, however I was wondering,
If Process A was to have a function like :
int DoStuff() { return 1; }
and a pointer typedef like :
typedef int(DoStuff_f*)();
and a getter function like :
DoStuff_f * getDoStuff() { return DoStuff; }
and a magical way to communicate with Process B via... say boost::interprocess
would it be possible to pass the function pointer to process B and call
Process A's DoStuff from Process B directly?
No. All a function pointer is is an address in your process's address space. It has no intrinsic marker that is unique to different processes. So, even if your function pointer just happened to still be valid once you've moved it over to B, it would call that function on behalf of process B.
For example, if you had
////PROCESS A////
int processA_myfun() { return 3; }
// get a pointer to pA_mf and pass it to process B
////PROCESS B////
int processB_myfun() { return 4; } // This happens to be at the same virtual address as pA_myfun
// get address from process A
int x = call_myfun(); // call via the pointer
x == 4; // x is 4, because we called process B's version!
If process A and B are running the same code, you might end up with identical functions at identical addresses - but you'll still be working with B's data structures and global memory! So the short answer is, no, this is not how you want to do this!
Also, security measures such as address space layout randomization could prevent these sort of "tricks" from ever working.
You're confusing IPC and RPC. IPC is for communicating data, such as your objects or a blob of text. RPC is for causing code to be executed in a remote process.
In short, you cannot use function pointer that passed to another process.
Codes of function are located in protected pages of memory, you cannot write to them. And each process has isolated virtual address space, so address of function is not valid in another process. In Windows you could use technique described in this article to inject your code in another process, but latest version of Windows rejects it.
Instead of passing function pointer, you should consider creating a library which will be used in both processes. In this case you could send message to another process when you need to call that function.
If you tried to use process A's function pointer from process B, you wouldn't be calling process A - you'd call whatever is at the same address in process B. If they are the same program you might get lucky and it will be the same code, but it won't have access to any of the data contained in process A.
A function pointer won't work for this, because it only contains the starting address for the code; if the code in question doesn't exist in the other process, or (due to something like address space randomization) is at a different location, the function pointer will be useless; in the second process, it will point to something, or nothing, but almost certainly not where you want it to.
You could, if you were insane^Wdaring, copy the actual instruction sequence onto the shared memory and then have the second process jump directly to it - but even if you could get this to work, the function would still run in Process B, not Process A.
It sounds like what you want is actually some sort of message-passing or RPC system.
This is why people have invented things like COM, RPC and CORBA. Each of them gives this general kind of capability. As you'd guess, each does so the job a bit differently from the others.
Boost IPC doesn't really support remote procedure calls. It will enable putting a variable in shared memory so its accessible to two processes, but if you want to use a getter/setter to access that variable, you'll have to do that yourself.
Those are all basically wrappers to produce a "palatable" version of something you can do without them though. In Windows, for example, you can put a variable in shared memory on your own. You can do the same in Linux. The Boost library is a fairly "thin" library around those, that lets you write the same code for Windows or Linux, but doesn't try to build a lot on top of that. CORBA (for one example) is a much thicker layer, providing a relatively complete distributed environment.
If both processes are in the same application, then this should work. If you are trying to send function pointers between applications then you are out of luck.
My original answer was correct if you assume a process and a thread are the same thing, which they're not. The other answers are correct - different processes cannot share function pointers (or any other kind of pointers, for that matter).