diff options
Diffstat (limited to 'cpp/src/Ice/UdpTransceiver.cpp')
-rw-r--r-- | cpp/src/Ice/UdpTransceiver.cpp | 34 |
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 } |