New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handling of file descriptor in win64 broken. #111
Comments
We could do that indeed. However, do you know how What do you think? |
zmq_pool() uses struct zmq_pollitem_t (see zmq.h):
This struct is in fact the place where SOCKET comes into play. So to answer your question zmq always uses the SOCKET type under windows in its api but somewhat hides that in zmq_pollitem_t. This is what gave me the idea to suggest the same thing for zmqpp. To summarize: making the change I suggested would 'repair' win64 and break the api for both win32 and win64 and do nothing to the other platforms. |
Yes using I don't grasp the whole problem since I am not familiar with the way file descriptor are represented on windows. Is there any case where using a simple |
The whole thing with file descriptors in this context is quite confusing because under windows there aren't any. ;-) This file descriptor concept comes from POSIX where file handles are used for things other than actual physical files on a disk. In Windows a file is really just a file. That is why the socket api in windows only uses 'sockets' and instead of using a 'file descriptor' they invented the SOCKET type. So I don't see any reason to keep the int version of The documentation of |
Thank you for clarifying the subject for me.
Ok.
Fair enough. Please submit a PR making those changes then :) |
Until now adding raw sockets to poller and reactor was done using a file descriptor as an int. This only works properly under POSIX. Under Windows a raw socket is represented as a SOCKET type. This type cannot simply be cast into int because under 32-bit it is actually an unsigned int and under 64-bit it is an unsigned __int64. The problem was solved by introducing a new typedef raw_socket_t which is of type SOCKET under Windows and an int under the other platforms. All methods taking an int as a file descriptor now take raw_socket_t hiding this platform detail away. The documention was changed accordingly to talk about 'standard socket' where 'file descriptor' was used before. This is a api-breaking change (at least under Windows). This fixes zeromq#111.
Improved the api dealing with file descriptors (see #111).
In the api a file descriptor (e.g. in poller::add()) is a simple int. But under Windows such a descriptor is actually of type SOCKET. This type is a typedef to UINT_PTR (see WinSock2.h). And here is the problem: Under 32bit UINT_PTR is an unsigned int, but under x64 it is an unsigned __int64. This means that the value of a file descriptor under x64 cannot not fit into an int. The compiler only warns about this but happily cuts off half of the value by casting the uint64 into int. In case of the poller this could have some unexpected side effects. Two distinct descriptors could be seen as the same because they only differ in the upper 32 bit. Worse than that is that the poller could do the wrong thing altogether because the 'broken' descriptor value is passed to zmq_poll().
A solution to this would be to not use int as the file descriptor but a type that is declared depending on the platform like this:
Of course this would break the public interface. But seeing that it only breaks for windows and it is already broken there, I see no other choice.
The text was updated successfully, but these errors were encountered: