Imported Upstream version 4.2.0.179

Former-commit-id: 4610231f55806d2a05ed69e5ff3faa7336cc1479
This commit is contained in:
Xamarin Public Jenkins
2015-08-26 07:17:56 -04:00
committed by Jo Shields
parent aa7da660d6
commit c042cd0c52
7507 changed files with 90259 additions and 657307 deletions

View File

@@ -0,0 +1,118 @@
//
// System.Net.Sockets.SafeSocketHandle
//
// Authors:
// Marcos Henrich <marcos.henrich@xamarin.com>
//
using System;
using System.IO;
using System.Threading;
using System.Collections.Generic;
using Microsoft.Win32.SafeHandles;
namespace System.Net.Sockets {
sealed class SafeSocketHandle : SafeHandleZeroOrMinusOneIsInvalid {
List<Thread> blocking_threads;
const int SOCKET_CLOSED = 10004;
const int ABORT_RETRIES = 10;
static bool THROW_ON_ABORT_RETRIES = Environment.GetEnvironmentVariable("MONO_TESTS_IN_PROGRESS") == "yes";
public SafeSocketHandle (IntPtr preexistingHandle, bool ownsHandle) : base (ownsHandle)
{
SetHandle (preexistingHandle);
}
// This is just for marshalling
internal SafeSocketHandle () : base (true)
{
}
protected override bool ReleaseHandle ()
{
int error = 0;
Socket.Blocking_internal (handle, false, out error);
if (blocking_threads != null) {
int abort_attempts = 0;
while (blocking_threads.Count > 0) {
if (abort_attempts++ >= ABORT_RETRIES) {
if (THROW_ON_ABORT_RETRIES)
throw new Exception ("Could not abort registered blocking threads before closing socket.");
// Attempts to close the socket safely failed.
// We give up, and close the socket with pending blocking system calls.
// This should not occur, nonetheless if it does this avoids an endless loop.
break;
}
/*
* This method can be called by the DangerousRelease inside RegisterForBlockingSyscall
* When this happens blocking_threads contains the current thread.
* We can safely close the socket and throw SocketException in RegisterForBlockingSyscall
* before the blocking system call.
*/
lock (blocking_threads) {
if (blocking_threads.Count == 1 && blocking_threads[0] == Thread.CurrentThread)
break;
}
AbortRegisteredThreads ();
// Sleep so other threads can resume
Thread.Sleep (1);
}
}
Socket.Close_internal (handle, out error);
return error == 0;
}
public void RegisterForBlockingSyscall ()
{
if (blocking_threads == null)
Interlocked.CompareExchange (ref blocking_threads, new List<Thread> (), null);
bool release = false;
try {
DangerousAddRef (ref release);
} finally {
/* We must use a finally block here to make this atomic. */
lock (blocking_threads) {
blocking_threads.Add (Thread.CurrentThread);
}
if (release)
DangerousRelease ();
// Handle can be closed by DangerousRelease
if (IsClosed)
throw new SocketException (SOCKET_CLOSED);
}
}
/* This must be called from a finally block! */
public void UnRegisterForBlockingSyscall ()
{
//If this NRE, we're in deep problems because Register Must have
lock (blocking_threads) {
blocking_threads.Remove (Thread.CurrentThread);
}
}
void AbortRegisteredThreads () {
if (blocking_threads == null)
return;
lock (blocking_threads) {
foreach (var t in blocking_threads)
Socket.cancel_blocking_socket_operation (t);
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
// System.Net.Sockets.SocketAsyncCallback.cs
//
// Authors:
// Ludovic Henry <ludovic@xamarin.com>
//
// Copyright (C) 2015 Xamarin, Inc. (https://www.xamarin.com)
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace System.Net.Sockets
{
internal delegate void SocketAsyncCallback (SocketAsyncResult sar);
}

View File

@@ -40,7 +40,7 @@ namespace System.Net.Sockets
{
bool disposed;
int in_progress;
internal Socket.Worker Worker;
internal SocketAsyncWorker Worker;
EndPoint remote_ep;
public Exception ConnectByNameError { get; internal set; }
@@ -101,7 +101,7 @@ namespace System.Net.Sockets
public SocketAsyncEventArgs ()
{
Worker = new Socket.Worker (this);
Worker = new SocketAsyncWorker (this);
AcceptSocket = null;
Buffer = null;
BufferList = null;
@@ -208,33 +208,42 @@ namespace System.Net.Sockets
static void DispatcherCB (IAsyncResult ares)
{
SocketAsyncEventArgs args = (SocketAsyncEventArgs) ares.AsyncState;
if (Interlocked.Exchange (ref args.in_progress, 0) != 1)
throw new InvalidOperationException ("No operation in progress");
SocketAsyncOperation op = args.LastOperation;
// Notes;
// -SocketOperation.AcceptReceive not used in SocketAsyncEventArgs
// -SendPackets and ReceiveMessageFrom are not implemented yet
if (op == SocketAsyncOperation.Receive)
args.ReceiveCallback (ares);
else if (op == SocketAsyncOperation.Send)
args.SendCallback (ares);
else if (op == SocketAsyncOperation.ReceiveFrom)
args.ReceiveFromCallback (ares);
else if (op == SocketAsyncOperation.SendTo)
args.SendToCallback (ares);
else if (op == SocketAsyncOperation.Accept)
args.AcceptCallback (ares);
else if (op == SocketAsyncOperation.Disconnect)
args.DisconnectCallback (ares);
else if (op == SocketAsyncOperation.Connect)
args.ConnectCallback (ares);
/*
else if (op == Socket.SocketOperation.ReceiveMessageFrom)
else if (op == Socket.SocketOperation.SendPackets)
*/
else
throw new NotImplementedException (String.Format ("Operation {0} is not implemented", op));
/* Notes;
* -SocketOperation.AcceptReceive not used in SocketAsyncEventArgs
* -SendPackets and ReceiveMessageFrom are not implemented yet */
switch (args.LastOperation) {
case SocketAsyncOperation.Receive:
args.ReceiveCallback (ares);
break;
case SocketAsyncOperation.Send:
args.SendCallback (ares);
break;
case SocketAsyncOperation.ReceiveFrom:
args.ReceiveFromCallback (ares);
break;
case SocketAsyncOperation.SendTo:
args.SendToCallback (ares);
break;
case SocketAsyncOperation.Accept:
args.AcceptCallback (ares);
break;
case SocketAsyncOperation.Disconnect:
args.DisconnectCallback (ares);
break;
case SocketAsyncOperation.Connect:
args.ConnectCallback (ares);
break;
/*
case SocketOperation.ReceiveMessageFrom:
case SocketOperation.SendPackets:
*/
default:
throw new NotImplementedException (String.Format ("Operation {0} is not implemented", args.LastOperation));
}
}
internal void ReceiveCallback (IAsyncResult ares)
@@ -286,7 +295,7 @@ namespace System.Net.Sockets
SocketError = SocketError.OperationAborted;
} finally {
if (AcceptSocket == null)
AcceptSocket = new Socket (curSocket.AddressFamily, curSocket.SocketType, curSocket.ProtocolType, (IntPtr)(-1));
AcceptSocket = new Socket (curSocket.AddressFamily, curSocket.SocketType, curSocket.ProtocolType, null);
OnCompleted (this);
}
}

View File

@@ -0,0 +1,318 @@
// System.Net.Sockets.SocketAsyncResult.cs
//
// Authors:
// Ludovic Henry <ludovic@xamarin.com>
//
// Copyright (C) 2015 Xamarin, Inc. (https://www.xamarin.com)
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Runtime.Remoting.Messaging;
using System.Threading;
namespace System.Net.Sockets
{
[StructLayout (LayoutKind.Sequential)]
internal sealed class SocketAsyncResult: IAsyncResult, IThreadPoolWorkItem
{
/* Same structure in the runtime. Keep this in sync with
* MonoSocketAsyncResult in metadata/socket-io.h and
* ProcessAsyncReader in System.Diagnostics/Process.cs. */
public Socket socket;
IntPtr handle;
object state;
AsyncCallback callback; // used from the runtime
WaitHandle wait_handle;
Exception delayed_exception;
public EndPoint EndPoint; // Connect,ReceiveFrom,SendTo
public byte [] Buffer; // Receive,ReceiveFrom,Send,SendTo
public int Offset; // Receive,ReceiveFrom,Send,SendTo
public int Size; // Receive,ReceiveFrom,Send,SendTo
public SocketFlags SockFlags; // Receive,ReceiveFrom,Send,SendTo
public Socket AcceptSocket; // AcceptReceive
public IPAddress[] Addresses; // Connect
public int Port; // Connect
public IList<ArraySegment<byte>> Buffers; // Receive, Send
public bool ReuseSocket; // Disconnect
// Return values
Socket accept_socket;
int total;
bool completed_synchronously;
bool completed;
bool is_blocking;
internal int error;
public SocketOperation operation;
AsyncResult async_result;
public int EndCalled;
/* These fields are not in MonoSocketAsyncResult */
public SocketAsyncWorker Worker;
public int CurrentAddress; // Connect
public SocketAsyncResult ()
{
}
public SocketAsyncResult (Socket socket, object state, AsyncCallback callback, SocketOperation operation)
{
Init (socket, state, callback, operation, new SocketAsyncWorker (this));
}
public object AsyncState {
get {
return state;
}
}
public WaitHandle AsyncWaitHandle {
get {
lock (this) {
if (wait_handle == null)
wait_handle = new ManualResetEvent (completed);
}
return wait_handle;
}
set {
wait_handle = value;
}
}
public bool CompletedSynchronously {
get {
return completed_synchronously;
}
}
public bool IsCompleted {
get {
return completed;
}
set {
completed = value;
lock (this) {
if (wait_handle != null && value)
((ManualResetEvent) wait_handle).Set ();
}
}
}
public Socket Socket {
get {
return accept_socket;
}
}
public int Total {
get { return total; }
set { total = value; }
}
public SocketError ErrorCode {
get {
SocketException ex = delayed_exception as SocketException;
if (ex != null)
return ex.SocketErrorCode;
if (error != 0)
return (SocketError) error;
return SocketError.Success;
}
}
public void Init (Socket socket, object state, AsyncCallback callback, SocketOperation operation, SocketAsyncWorker worker)
{
this.socket = socket;
this.is_blocking = socket != null ? socket.is_blocking : true;
this.handle = socket != null ? socket.Handle : IntPtr.Zero;
this.state = state;
this.callback = callback;
this.operation = operation;
if (wait_handle != null)
((ManualResetEvent) wait_handle).Reset ();
delayed_exception = null;
EndPoint = null;
Buffer = null;
Offset = 0;
Size = 0;
SockFlags = SocketFlags.None;
AcceptSocket = null;
Addresses = null;
Port = 0;
Buffers = null;
ReuseSocket = false;
accept_socket = null;
total = 0;
completed_synchronously = false;
completed = false;
is_blocking = false;
error = 0;
async_result = null;
EndCalled = 0;
Worker = worker;
}
public void DoMConnectCallback ()
{
if (callback == null)
return;
ThreadPool.UnsafeQueueUserWorkItem (_ => callback (this), null);
}
public void Dispose ()
{
Init (null, null, null, 0, Worker);
if (wait_handle != null) {
wait_handle.Close ();
wait_handle = null;
}
}
public void CheckIfThrowDelayedException ()
{
if (delayed_exception != null) {
socket.is_connected = false;
throw delayed_exception;
}
if (error != 0) {
socket.is_connected = false;
throw new SocketException (error);
}
}
void CompleteDisposed (object unused)
{
Complete ();
}
public void Complete ()
{
if (operation != SocketOperation.Receive && socket.is_disposed)
delayed_exception = new ObjectDisposedException (socket.GetType ().ToString ());
IsCompleted = true;
Queue<SocketAsyncWorker> queue = null;
switch (operation) {
case SocketOperation.Receive:
case SocketOperation.ReceiveFrom:
case SocketOperation.ReceiveGeneric:
case SocketOperation.Accept:
queue = socket.readQ;
break;
case SocketOperation.Send:
case SocketOperation.SendTo:
case SocketOperation.SendGeneric:
queue = socket.writeQ;
break;
}
if (queue != null) {
lock (queue) {
/* queue.Count will only be 0 if the socket is closed while receive/send/accept
* operation(s) are pending and at least one call to this method is waiting
* on the lock while another one calls CompleteAllOnDispose() */
if (queue.Count > 0)
queue.Dequeue (); /* remove ourselves */
if (queue.Count > 0) {
if (!socket.is_disposed) {
Socket.socket_pool_queue (SocketAsyncWorker.Dispatcher, (queue.Peek ()).result);
} else {
/* CompleteAllOnDispose */
SocketAsyncWorker [] workers = queue.ToArray ();
for (int i = 0; i < workers.Length; i++)
ThreadPool.UnsafeQueueUserWorkItem (workers [i].result.CompleteDisposed, null);
queue.Clear ();
}
}
}
}
// IMPORTANT: 'callback', if any is scheduled from unmanaged code
}
public void Complete (bool synch)
{
this.completed_synchronously = synch;
Complete ();
}
public void Complete (int total)
{
this.total = total;
Complete ();
}
public void Complete (Exception e, bool synch)
{
this.completed_synchronously = synch;
this.delayed_exception = e;
Complete ();
}
public void Complete (Exception e)
{
this.delayed_exception = e;
Complete ();
}
public void Complete (Socket s)
{
this.accept_socket = s;
Complete ();
}
public void Complete (Socket s, int total)
{
this.accept_socket = s;
this.total = total;
Complete ();
}
void IThreadPoolWorkItem.ExecuteWorkItem()
{
async_result.Invoke ();
if (completed && callback != null) {
ThreadPool.UnsafeQueueCustomWorkItem (new AsyncResult (state => callback ((IAsyncResult) state), this, false), false);
}
}
void IThreadPoolWorkItem.MarkAborted(ThreadAbortException tae)
{
}
}
}

View File

@@ -0,0 +1,397 @@
// System.Net.Sockets.SocketAsyncWorker.cs
//
// Authors:
// Ludovic Henry <ludovic@xamarin.com>
//
// Copyright (C) 2015 Xamarin, Inc. (https://www.xamarin.com)
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace System.Net.Sockets
{
internal sealed class SocketAsyncWorker
{
public SocketAsyncResult result;
SocketAsyncEventArgs args;
public SocketAsyncWorker (SocketAsyncEventArgs args)
{
this.args = args;
result = new SocketAsyncResult ();
result.Worker = this;
}
public SocketAsyncWorker (SocketAsyncResult ares)
{
this.result = ares;
}
public void Dispose ()
{
if (result != null) {
result.Dispose ();
result = null;
args = null;
}
}
public static SocketAsyncCallback Dispatcher = new SocketAsyncCallback (DispatcherCB);
static void DispatcherCB (SocketAsyncResult sar)
{
/* SendPackets and ReceiveMessageFrom are not implemented yet */
switch (sar.operation) {
case SocketOperation.Receive:
case SocketOperation.ReceiveGeneric:
case SocketOperation.RecvJustCallback:
sar.Worker.Receive ();
break;
case SocketOperation.Send:
case SocketOperation.SendGeneric:
case SocketOperation.SendJustCallback:
sar.Worker.Send ();
break;
case SocketOperation.ReceiveFrom:
sar.Worker.ReceiveFrom ();
break;
case SocketOperation.SendTo:
sar.Worker.SendTo ();
break;
case SocketOperation.Connect:
sar.Worker.Connect ();
break;
case SocketOperation.Accept:
sar.Worker.Accept ();
break;
case SocketOperation.AcceptReceive:
sar.Worker.AcceptReceive ();
break;
case SocketOperation.Disconnect:
sar.Worker.Disconnect ();
break;
// case SocketOperation.ReceiveMessageFrom
// sar.Worker.ReceiveMessageFrom ()
// break;
// case SocketOperation.SendPackets:
// sar.Worker.SendPackets ();
// break;
default:
throw new NotImplementedException (String.Format ("Operation {0} is not implemented", sar.operation));
}
}
/* This is called when reusing a SocketAsyncEventArgs */
public void Init (Socket sock, SocketAsyncEventArgs args, SocketOperation op)
{
result.Init (sock, args, SocketAsyncEventArgs.Dispatcher, op, this);
SocketAsyncOperation async_op;
// Notes;
// -SocketOperation.AcceptReceive not used in SocketAsyncEventArgs
// -SendPackets and ReceiveMessageFrom are not implemented yet
switch (op) {
case SocketOperation.Connect:
async_op = SocketAsyncOperation.Connect;
break;
case SocketOperation.Accept:
async_op = SocketAsyncOperation.Accept;
break;
case SocketOperation.Disconnect:
async_op = SocketAsyncOperation.Disconnect;
break;
case SocketOperation.Receive:
case SocketOperation.ReceiveGeneric:
async_op = SocketAsyncOperation.Receive;
break;
case SocketOperation.ReceiveFrom:
async_op = SocketAsyncOperation.ReceiveFrom;
break;
// case SocketOperation.ReceiveMessageFrom:
// async_op = SocketAsyncOperation.ReceiveMessageFrom;
// break;
case SocketOperation.Send:
case SocketOperation.SendGeneric:
async_op = SocketAsyncOperation.Send;
break;
// case SocketOperation.SendPackets:
// async_op = SocketAsyncOperation.SendPackets;
// break;
case SocketOperation.SendTo:
async_op = SocketAsyncOperation.SendTo;
break;
default:
throw new NotImplementedException (String.Format ("Operation {0} is not implemented", op));
}
args.SetLastOperation (async_op);
args.SocketError = SocketError.Success;
args.BytesTransferred = 0;
}
public void Accept ()
{
Socket acc_socket = null;
try {
if (args != null && args.AcceptSocket != null) {
result.socket.Accept (args.AcceptSocket);
acc_socket = args.AcceptSocket;
} else {
acc_socket = result.socket.Accept ();
if (args != null)
args.AcceptSocket = acc_socket;
}
} catch (Exception e) {
result.Complete (e);
return;
}
result.Complete (acc_socket);
}
/* only used in 2.0 profile and newer, but
* leave in older profiles to keep interface
* to runtime consistent
*/
public void AcceptReceive ()
{
Socket acc_socket = null;
try {
if (result.AcceptSocket == null) {
acc_socket = result.socket.Accept ();
} else {
acc_socket = result.AcceptSocket;
result.socket.Accept (acc_socket);
}
} catch (Exception e) {
result.Complete (e);
return;
}
/* It seems the MS runtime
* special-cases 0-length requested
* receive data. See bug 464201.
*/
int total = 0;
if (result.Size > 0) {
try {
SocketError error;
total = acc_socket.Receive_nochecks (result.Buffer, result.Offset, result.Size, result.SockFlags, out error);
if (error != 0) {
result.Complete (new SocketException ((int) error));
return;
}
} catch (Exception e) {
result.Complete (e);
return;
}
}
result.Complete (acc_socket, total);
}
public void Connect ()
{
if (result.EndPoint == null) {
result.Complete (new SocketException ((int)SocketError.AddressNotAvailable));
return;
}
SocketAsyncResult mconnect = result.AsyncState as SocketAsyncResult;
bool is_mconnect = (mconnect != null && mconnect.Addresses != null);
try {
int error_code;
EndPoint ep = result.EndPoint;
error_code = (int) result.socket.GetSocketOption (SocketOptionLevel.Socket, SocketOptionName.Error);
if (error_code == 0) {
if (is_mconnect)
result = mconnect;
result.socket.seed_endpoint = ep;
result.socket.is_connected = true;
result.socket.is_bound = true;
result.socket.connect_in_progress = false;
result.error = 0;
result.Complete ();
if (is_mconnect)
result.DoMConnectCallback ();
return;
}
if (!is_mconnect) {
result.socket.connect_in_progress = false;
result.Complete (new SocketException (error_code));
return;
}
if (mconnect.CurrentAddress >= mconnect.Addresses.Length) {
mconnect.Complete (new SocketException (error_code));
if (is_mconnect)
mconnect.DoMConnectCallback ();
return;
}
mconnect.socket.BeginMConnect (mconnect);
} catch (Exception e) {
result.socket.connect_in_progress = false;
if (is_mconnect)
result = mconnect;
result.Complete (e);
if (is_mconnect)
result.DoMConnectCallback ();
return;
}
}
/* Also only used in 2.0 profile and newer */
public void Disconnect ()
{
try {
if (args != null)
result.ReuseSocket = args.DisconnectReuseSocket;
result.socket.Disconnect (result.ReuseSocket);
} catch (Exception e) {
result.Complete (e);
return;
}
result.Complete ();
}
public void Receive ()
{
if (result.operation == SocketOperation.ReceiveGeneric) {
ReceiveGeneric ();
return;
}
int total = 0;
try {
total = Socket.Receive_internal (result.socket.safe_handle, result.Buffer, result.Offset, result.Size, result.SockFlags, out result.error);
} catch (Exception e) {
result.Complete (e);
return;
}
result.Complete (total);
}
public void ReceiveFrom ()
{
int total = 0;
try {
total = result.socket.ReceiveFrom_nochecks (result.Buffer, result.Offset, result.Size, result.SockFlags, ref result.EndPoint);
} catch (Exception e) {
result.Complete (e);
return;
}
result.Complete (total);
}
public void ReceiveGeneric ()
{
int total = 0;
try {
total = result.socket.Receive (result.Buffers, result.SockFlags);
} catch (Exception e) {
result.Complete (e);
return;
}
result.Complete (total);
}
int send_so_far;
void UpdateSendValues (int last_sent)
{
if (result.error == 0) {
send_so_far += last_sent;
result.Offset += last_sent;
result.Size -= last_sent;
}
}
public void Send ()
{
if (result.operation == SocketOperation.SendGeneric) {
SendGeneric ();
return;
}
int total = 0;
try {
total = Socket.Send_internal (result.socket.safe_handle, result.Buffer, result.Offset, result.Size, result.SockFlags, out result.error);
} catch (Exception e) {
result.Complete (e);
return;
}
if (result.error == 0) {
UpdateSendValues (total);
if (result.socket.is_disposed) {
result.Complete (total);
return;
}
if (result.Size > 0) {
Socket.socket_pool_queue (SocketAsyncWorker.Dispatcher, result);
return; // Have to finish writing everything. See bug #74475.
}
result.Total = send_so_far;
send_so_far = 0;
}
result.Complete (total);
}
public void SendTo ()
{
int total = 0;
try {
total = result.socket.SendTo_nochecks (result.Buffer, result.Offset, result.Size, result.SockFlags, result.EndPoint);
UpdateSendValues (total);
if (result.Size > 0) {
Socket.socket_pool_queue (SocketAsyncWorker.Dispatcher, result);
return; // Have to finish writing everything. See bug #74475.
}
result.Total = send_so_far;
send_so_far = 0;
} catch (Exception e) {
send_so_far = 0;
result.Complete (e);
return;
}
result.Complete ();
}
public void SendGeneric ()
{
int total = 0;
try {
total = result.socket.Send (result.Buffers, result.SockFlags);
} catch (Exception e) {
result.Complete (e);
return;
}
result.Complete (total);
}
}
}

View File

@@ -0,0 +1,48 @@
// System.Net.Sockets.SocketOperation.cs
//
// Authors:
// Ludovic Henry <ludovic@xamarin.com>
//
// Copyright (C) 2015 Xamarin, Inc. (https://www.xamarin.com)
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace System.Net.Sockets
{
// Used by the runtime
internal enum SocketOperation {
Accept,
Connect,
Receive,
ReceiveFrom,
Send,
SendTo,
RecvJustCallback,
SendJustCallback,
UsedInProcess,
UsedInConsole2,
Disconnect,
AcceptReceive,
ReceiveGeneric,
SendGeneric
}
}

View File

@@ -1,207 +0,0 @@
// SocketOptionName.cs
//
// This code was automatically generated from
// ECMA CLI XML Library Specification.
// Generator: libgen.xsl [1.0; (C) Sergey Chaban (serge@wildwestsoftware.com)]
// Created: Wed, 5 Sep 2001 06:33:02 UTC
// Source file: AllTypes.xml
// URL: http://msdn.microsoft.com/net/ecma/AllTypes.xml
//
// (C) 2001 Ximian, Inc. http://www.ximian.com
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace System.Net.Sockets {
/// <summary>
/// </summary>
public enum SocketOptionName {
/// <summary>
/// </summary>
Debug = 1,
/// <summary>
/// </summary>
AcceptConnection = 2,
/// <summary>
/// </summary>
ReuseAddress = 4,
/// <summary>
/// </summary>
KeepAlive = 8,
/// <summary>
/// </summary>
DontRoute = 16,
/// <summary>
/// </summary>
Broadcast = 32,
/// <summary>
/// </summary>
UseLoopback = 64,
/// <summary>
/// </summary>
Linger = 128,
/// <summary>
/// </summary>
OutOfBandInline = 256,
/// <summary>
/// </summary>
DontLinger = -129,
/// <summary>
/// </summary>
ExclusiveAddressUse = -5,
/// <summary>
/// </summary>
SendBuffer = 4097,
/// <summary>
/// </summary>
ReceiveBuffer = 4098,
/// <summary>
/// </summary>
SendLowWater = 4099,
/// <summary>
/// </summary>
ReceiveLowWater = 4100,
/// <summary>
/// </summary>
SendTimeout = 4101,
/// <summary>
/// </summary>
ReceiveTimeout = 4102,
/// <summary>
/// </summary>
Error = 4103,
/// <summary>
/// </summary>
Type = 4104,
/// <summary>
/// </summary>
MaxConnections = 2147483647,
/// <summary>
/// </summary>
IPOptions = 1,
/// <summary>
/// </summary>
HeaderIncluded = 2,
/// <summary>
/// </summary>
TypeOfService = 3,
/// <summary>
/// </summary>
IpTimeToLive = 4,
/// <summary>
/// </summary>
MulticastInterface = 9,
/// <summary>
/// </summary>
MulticastTimeToLive = 10,
/// <summary>
/// </summary>
MulticastLoopback = 11,
/// <summary>
/// </summary>
AddMembership = 12,
/// <summary>
/// </summary>
DropMembership = 13,
/// <summary>
/// </summary>
DontFragment = 14,
/// <summary>
/// </summary>
AddSourceMembership = 15,
/// <summary>
/// </summary>
DropSourceMembership = 16,
/// <summary>
/// </summary>
BlockSource = 17,
/// <summary>
/// </summary>
UnblockSource = 18,
/// <summary>
/// </summary>
PacketInformation = 19,
/// <summary>
/// </summary>
NoDelay = 1,
/// <summary>
/// </summary>
BsdUrgent = 2,
/// <summary>
/// </summary>
Expedited = 2,
/// <summary>
/// </summary>
NoChecksum = 1,
/// <summary>
/// </summary>
ChecksumCoverage = 20,
HopLimit = 21,
UpdateAcceptContext = 28683,
UpdateConnectContext = 28688,
} // SocketOptionName
} // System.Net.Sockets

File diff suppressed because it is too large Load Diff