summaryrefslogtreecommitdiff
path: root/cpp/src/Ice/UdpTransceiver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/Ice/UdpTransceiver.cpp')
-rw-r--r--cpp/src/Ice/UdpTransceiver.cpp34
1 files changed, 28 insertions, 6 deletions
diff --git a/cpp/src/Ice/UdpTransceiver.cpp b/cpp/src/Ice/UdpTransceiver.cpp
index b0392ad9cfd..c664eeb977e 100644
--- a/cpp/src/Ice/UdpTransceiver.cpp
+++ b/cpp/src/Ice/UdpTransceiver.cpp
@@ -124,6 +124,7 @@ IceInternal::UdpTransceiver::close()
_readPending = false;
}
_received.clear();
+ _completedHandler = nullptr;
#endif
assert(_fd != INVALID_SOCKET);
@@ -389,6 +390,7 @@ IceInternal::UdpTransceiver::startWrite(Buffer& buf)
auto operation = safe_cast<DatagramSocket^>(_fd)->ConnectAsync(_addr.host, _addr.port);
if(!checkIfErrorOrCompleted(SocketOperationConnect, operation))
{
+ SocketOperationCompletedHandler^ completed = _completedHandler;
operation->Completed = ref new AsyncActionCompletedHandler(
[=] (IAsyncAction^ info, Windows::Foundation::AsyncStatus status)
{
@@ -402,7 +404,7 @@ IceInternal::UdpTransceiver::startWrite(Buffer& buf)
_write.count = 0;
_writer = ref new DataWriter(safe_cast<DatagramSocket^>(_fd)->OutputStream);
}
- _completedHandler(SocketOperationConnect);
+ completed(SocketOperationConnect);
});
}
else
@@ -416,6 +418,7 @@ IceInternal::UdpTransceiver::startWrite(Buffer& buf)
auto operation = safe_cast<DatagramSocket^>(_fd)->GetOutputStreamAsync(_addr.host, _addr.port);
if(!checkIfErrorOrCompleted(SocketOperationConnect, operation))
{
+ SocketOperationCompletedHandler^ completed = _completedHandler;
operation->Completed = ref new AsyncOperationCompletedHandler<IOutputStream^>(
[=] (IAsyncOperation<IOutputStream^>^ info, Windows::Foundation::AsyncStatus status)
{
@@ -433,7 +436,7 @@ IceInternal::UdpTransceiver::startWrite(Buffer& buf)
{
setMcastGroup(_fd, _mcastAddr, "");
}
- _completedHandler(SocketOperationConnect);
+ completed(SocketOperationConnect);
});
}
else
@@ -457,6 +460,7 @@ IceInternal::UdpTransceiver::startWrite(Buffer& buf)
{
try
{
+ SocketOperationCompletedHandler^ completed = _completedHandler;
DatagramSocket^ fd = safe_cast<DatagramSocket^>(_fd);
concurrency::create_task(fd->GetOutputStreamAsync(_peerAddr.host, _peerAddr.port)).then(
[=,&buf](concurrency::task<IOutputStream^> task)
@@ -478,7 +482,7 @@ IceInternal::UdpTransceiver::startWrite(Buffer& buf)
// completed callback.
//
_write.count = operation->GetResults();
- _completedHandler(SocketOperationWrite);
+ completed(SocketOperationWrite);
}
else if(status == Windows::Foundation::AsyncStatus::Started)
{
@@ -500,7 +504,7 @@ IceInternal::UdpTransceiver::startWrite(Buffer& buf)
{
_write.count = SOCKET_ERROR;
_write.error = pex->HResult;
- _completedHandler(SocketOperationWrite);
+ completed(SocketOperationWrite);
}
});
}
@@ -952,10 +956,19 @@ IceInternal::UdpTransceiver::UdpTransceiver(const ProtocolInstancePtr& instance,
}
#else
DatagramSocket^ socket = safe_cast<DatagramSocket^>(_fd);
+ IceUtil::Handle<UdpTransceiver> self(this);
+# if _WIN32_WINNT >= 0x0A00
+ // On Windows 10, it's necessary to set this property to allow Win32 applications to
+ // bind to the same multicast address
+ if(isMulticast(_addr))
+ {
+ socket->Control->MulticastOnly = true;
+ }
+# endif
socket->MessageReceived += ref new TypedEventHandler<DatagramSocket^, DatagramSocketMessageReceivedEventArgs^>(
[=](DatagramSocket^ fd, DatagramSocketMessageReceivedEventArgs^ args)
{
- this->appendMessage(args);
+ self->appendMessage(args);
});
#endif
@@ -999,10 +1012,19 @@ IceInternal::UdpTransceiver::UdpTransceiver(const UdpEndpointIPtr& endpoint, con
_mcastAddr.saStorage.ss_family = AF_UNSPEC;
#else
DatagramSocket^ socket = safe_cast<DatagramSocket^>(_fd);
+# if _WIN32_WINNT >= 0x0A00
+ // On Windows 10, it's necessary to set this property to allow Win32 applications to
+ // bind to the same multicast address
+ if(isMulticast(_addr))
+ {
+ socket->Control->MulticastOnly = true;
+ }
+# endif
+ IceUtil::Handle<UdpTransceiver> self(this);
socket->MessageReceived += ref new TypedEventHandler<DatagramSocket^, DatagramSocketMessageReceivedEventArgs^>(
[=](DatagramSocket^ fd, DatagramSocketMessageReceivedEventArgs^ args)
{
- this->appendMessage(args);
+ self->appendMessage(args);
});
#endif
}