Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:netway:mono
mono
mono-3.4.0-140809.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File mono-3.4.0-140809.diff of Package mono
diff --git a/mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs b/mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs index 354dba9..ffa832a 100644 --- a/mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs +++ b/mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs @@ -311,6 +311,11 @@ namespace System.Net.Http var stream = await wrequest.GetRequestStreamAsync ().ConfigureAwait (false); await request.Content.CopyToAsync (stream).ConfigureAwait (false); + } else if (HttpMethod.Post.Equals (request.Method) || HttpMethod.Put.Equals (request.Method) || HttpMethod.Delete.Equals (request.Method)) { + // Explicitly set this to make sure we're sending a "Content-Length: 0" header. + // This fixes the issue that's been reported on the forums: + // http://forums.xamarin.com/discussion/17770/length-required-error-in-http-post-since-latest-release + wrequest.ContentLength = 0; } HttpWebResponse wresponse = null; diff --git a/mcs/class/System.Net.Http/Test/System.Net.Http/HttpClientTest.cs b/mcs/class/System.Net.Http/Test/System.Net.Http/HttpClientTest.cs index 818a90d..8b595d8 100644 --- a/mcs/class/System.Net.Http/Test/System.Net.Http/HttpClientTest.cs +++ b/mcs/class/System.Net.Http/Test/System.Net.Http/HttpClientTest.cs @@ -534,6 +534,38 @@ namespace MonoTests.System.Net.Http } [Test] + public void Send_Complete_NoContent () + { + foreach (var method in new HttpMethod[] { HttpMethod.Post, HttpMethod.Put, HttpMethod.Delete }) { + bool? failed = null; + var listener = CreateListener (l => { + try { + var request = l.Request; + + Assert.AreEqual (2, request.Headers.Count, "#1"); + Assert.AreEqual ("0", request.Headers ["Content-Length"], "#1b"); + Assert.AreEqual (method.Method, request.HttpMethod, "#2"); + failed = false; + } catch { + failed = true; + } + }); + + try { + var client = new HttpClient (); + var request = new HttpRequestMessage (method, LocalServer); + var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result; + + Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100"); + Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101"); + Assert.AreEqual (false, failed, "#102"); + } finally { + listener.Close (); + } + } + } + + [Test] public void Send_Complete_Error () { var listener = CreateListener (l => { diff --git a/mcs/class/System/System.Net/HttpWebRequest.cs b/mcs/class/System/System.Net/HttpWebRequest.cs index cfee239..9dbf485 100644 --- a/mcs/class/System/System.Net/HttpWebRequest.cs +++ b/mcs/class/System/System.Net/HttpWebRequest.cs @@ -865,29 +865,29 @@ namespace System.Net return EndGetRequestStream (asyncResult); } - WebAsyncResult CheckIfForceWrite (AsyncCallback callback, object state) + bool CheckIfForceWrite (SimpleAsyncResult result) { if (writeStream == null || writeStream.RequestWritten || !InternalAllowBuffering) - return null; -#if NET_4_0 + return false; + #if NET_4_0 if (contentLength < 0 && writeStream.CanWrite == true && writeStream.WriteBufferLength < 0) - return null; + return false; if (contentLength < 0 && writeStream.WriteBufferLength >= 0) InternalContentLength = writeStream.WriteBufferLength; -#else + #else if (contentLength < 0 && writeStream.CanWrite == true) - return null; -#endif + return false; + #endif // This will write the POST/PUT if the write stream already has the expected // amount of bytes in it (ContentLength) (bug #77753) or if the write stream // contains data and it has been closed already (xamarin bug #1512). if (writeStream.WriteBufferLength == contentLength || (contentLength == -1 && writeStream.CanWrite == false)) - return writeStream.WriteRequestAsync (callback, state); + return writeStream.WriteRequestAsync (result); - return null; + return false; } public override IAsyncResult BeginGetResponse (AsyncCallback callback, object state) @@ -914,59 +914,41 @@ namespace System.Net WebAsyncResult aread = asyncRead; initialMethod = method; - aread.InnerAsyncResult = CheckIfForceWrite (GetResponseAsyncCB, aread); - if (aread.InnerAsyncResult == null) - GetResponseAsyncCB2 (aread); - else - Monitor.Exit (locker); - return aread; - } + SimpleAsyncResult.RunWithLock (locker, CheckIfForceWrite, inner => { + var synch = inner.CompletedSynchronously; - void GetResponseAsyncCB (IAsyncResult ar) - { - var result = (WebAsyncResult)ar; - var innerResult = (WebAsyncResult)result.InnerAsyncResult; - result.InnerAsyncResult = null; - - if (innerResult != null && innerResult.GotException) { - asyncRead.SetCompleted (true, innerResult.Exception); - asyncRead.DoCallback (); - return; - } - - Monitor.Enter (locker); - GetResponseAsyncCB2 ((WebAsyncResult)ar); - } - - void GetResponseAsyncCB2 (WebAsyncResult aread) - { - if (haveResponse) { - Exception saved = saved_exc; - if (webResponse != null) { - Monitor.Exit (locker); - if (saved == null) { - aread.SetCompleted (true, webResponse); - } else { - aread.SetCompleted (true, saved); - } - aread.DoCallback (); - return; - } else if (saved != null) { - Monitor.Exit (locker); - aread.SetCompleted (true, saved); + if (inner.GotException) { + aread.SetCompleted (synch, inner.Exception); aread.DoCallback (); return; } - } - if (!requestSent) { - requestSent = true; - redirects = 0; - servicePoint = GetServicePoint (); - abortHandler = servicePoint.SendRequest (this, connectionGroup); - } + if (haveResponse) { + Exception saved = saved_exc; + if (webResponse != null) { + if (saved == null) { + aread.SetCompleted (synch, webResponse); + } else { + aread.SetCompleted (synch, saved); + } + aread.DoCallback (); + return; + } else if (saved != null) { + aread.SetCompleted (synch, saved); + aread.DoCallback (); + return; + } + } - Monitor.Exit (locker); + if (!requestSent) { + requestSent = true; + redirects = 0; + servicePoint = GetServicePoint (); + abortHandler = servicePoint.SendRequest (this, connectionGroup); + } + }); + + return aread; } public override WebResponse EndGetResponse (IAsyncResult asyncResult) @@ -1323,69 +1305,58 @@ namespace System.Net writeStream.SendChunked = false; } - try { - var result = writeStream.SetHeadersAsync (false, SetWriteStreamCB, null); - if (result == null) - SetWriteStreamCB (null); - } catch (Exception exc) { - SetWriteStreamErrorCB (exc); - } - } - - void SetWriteStreamErrorCB (Exception exc) - { - WebException wexc = exc as WebException; - if (wexc != null) - SetWriteStreamError (wexc.Status, wexc); - else - SetWriteStreamError (WebExceptionStatus.SendFailure, exc); - } + writeStream.SetHeadersAsync (false, result => { + if (result.GotException) { + SetWriteStreamError (result.Exception); + return; + } - void SetWriteStreamCB (IAsyncResult ar) - { - WebAsyncResult result = ar as WebAsyncResult; + haveRequest = true; - if (result != null && result.Exception != null) { - SetWriteStreamErrorCB (result.Exception); - return; - } - - haveRequest = true; + SetWriteStreamInner (inner => { + if (inner.GotException) { + SetWriteStreamError (inner.Exception); + return; + } - WebAsyncResult writeRequestResult = null; + if (asyncWrite != null) { + asyncWrite.SetCompleted (inner.CompletedSynchronously, writeStream); + asyncWrite.DoCallback (); + asyncWrite = null; + } + }); + }); + } - if (bodyBuffer != null) { - // The body has been written and buffered. The request "user" - // won't write it again, so we must do it. - if (auth_state.NtlmAuthState != NtlmAuthState.Challenge && proxy_auth_state.NtlmAuthState != NtlmAuthState.Challenge) { - // FIXME: this is a blocking call on the thread pool that could lead to thread pool exhaustion - writeStream.Write (bodyBuffer, 0, bodyBufferLength); - bodyBuffer = null; - writeStream.Close (); + SimpleAsyncResult SetWriteStreamInner (SimpleAsyncCallback callback) + { + return SimpleAsyncResult.Run (result => { + if (bodyBuffer != null) { + // The body has been written and buffered. The request "user" + // won't write it again, so we must do it. + if (auth_state.NtlmAuthState != NtlmAuthState.Challenge && proxy_auth_state.NtlmAuthState != NtlmAuthState.Challenge) { + // FIXME: this is a blocking call on the thread pool that could lead to thread pool exhaustion + writeStream.Write (bodyBuffer, 0, bodyBufferLength); + bodyBuffer = null; + writeStream.Close (); + } + } else if (method != "HEAD" && method != "GET" && method != "MKCOL" && method != "CONNECT" && + method != "TRACE") { + if (getResponseCalled && !writeStream.RequestWritten) + return writeStream.WriteRequestAsync (result); } - } else if (method != "HEAD" && method != "GET" && method != "MKCOL" && method != "CONNECT" && - method != "TRACE") { - if (getResponseCalled && !writeStream.RequestWritten) - writeRequestResult = writeStream.WriteRequestAsync (SetWriteStreamCB2, null); - } - if (writeRequestResult == null) - SetWriteStreamCB2 (null); + return false; + }, callback); } - void SetWriteStreamCB2 (IAsyncResult ar) + void SetWriteStreamError (Exception exc) { - var result = (WebAsyncResult)ar; - if (result != null && result.GotException) { - SetWriteStreamErrorCB (result.Exception); - return; - } - - if (asyncWrite != null) { - asyncWrite.SetCompleted (false, writeStream); - asyncWrite.DoCallback (); - asyncWrite = null; - } + WebException wexc = exc as WebException; + if (wexc != null) + SetWriteStreamError (wexc.Status, wexc); + else + SetWriteStreamError (WebExceptionStatus.SendFailure, exc); } internal void SetResponseError (WebExceptionStatus status, Exception e, string where) diff --git a/mcs/class/System/System.Net/ServicePoint.cs b/mcs/class/System/System.Net/ServicePoint.cs index 663816e..1d72e56 100644 --- a/mcs/class/System/System.Net/ServicePoint.cs +++ b/mcs/class/System/System.Net/ServicePoint.cs @@ -52,7 +52,6 @@ namespace System.Net X509Certificate clientCertificate; IPHostEntry host; bool usesProxy; - WebConnectionGroup firstGroup; Dictionary<string,WebConnectionGroup> groups; bool sendContinue = true; bool useConnect; @@ -255,45 +254,25 @@ namespace System.Net */ WebConnectionGroup group; - if (firstGroup != null && name == firstGroup.Name) - return firstGroup; if (groups != null && groups.TryGetValue (name, out group)) return group; group = new WebConnectionGroup (this, name); group.ConnectionClosed += (s, e) => currentConnections--; - if (firstGroup == null) - firstGroup = group; - else { - if (groups == null) - groups = new Dictionary<string, WebConnectionGroup> (); - groups.Add (name, group); - } + if (groups == null) + groups = new Dictionary<string, WebConnectionGroup> (); + groups.Add (name, group); return group; } void RemoveConnectionGroup (WebConnectionGroup group) { - if (groups == null || groups.Count == 0) { - // No more connection groups left. - if (group != firstGroup) - throw new InvalidOperationException (); - else - firstGroup = null; - return; - } + if (groups == null || groups.Count == 0) + throw new InvalidOperationException (); - if (group == firstGroup) { - // Steal one entry from the dictionary. - var en = groups.GetEnumerator (); - en.MoveNext (); - firstGroup = en.Current.Value; - groups.Remove (en.Current.Key); - } else { - groups.Remove (group.Name); - } + groups.Remove (group.Name); } internal bool CheckAvailableForRecycling (out DateTime outIdleSince) @@ -301,10 +280,9 @@ namespace System.Net outIdleSince = DateTime.MinValue; TimeSpan idleTimeSpan; - WebConnectionGroup singleGroup, singleRemove = null; List<WebConnectionGroup> groupList = null, removeList = null; lock (this) { - if (firstGroup == null) { + if (groups == null || groups.Count == 0) { idleSince = DateTime.MinValue; return true; } @@ -320,30 +298,20 @@ namespace System.Net * */ - singleGroup = firstGroup; - if (groups != null) - groupList = new List<WebConnectionGroup> (groups.Values); + groupList = new List<WebConnectionGroup> (groups.Values); } - if (singleGroup.TryRecycle (idleTimeSpan, ref outIdleSince)) - singleRemove = singleGroup; - - if (groupList != null) { - foreach (var group in groupList) { - if (!group.TryRecycle (idleTimeSpan, ref outIdleSince)) - continue; - if (removeList == null) - removeList = new List<WebConnectionGroup> (); - removeList.Add (group); - } + foreach (var group in groupList) { + if (!group.TryRecycle (idleTimeSpan, ref outIdleSince)) + continue; + if (removeList == null) + removeList = new List<WebConnectionGroup> (); + removeList.Add (group); } lock (this) { idleSince = outIdleSince; - if (singleRemove != null) - RemoveConnectionGroup (singleRemove); - if (removeList != null) { foreach (var group in removeList) RemoveConnectionGroup (group); @@ -352,9 +320,11 @@ namespace System.Net if (groups != null && groups.Count == 0) groups = null; - if (firstGroup == null) { - idleTimer.Dispose (); - idleTimer = null; + if (groups == null) { + if (idleTimer != null) { + idleTimer.Dispose (); + idleTimer = null; + } return true; } diff --git a/mcs/class/System/System.Net/ServicePointManager.cs b/mcs/class/System/System.Net/ServicePointManager.cs index ba9e9dc..3a7d66a 100644 --- a/mcs/class/System/System.Net/ServicePointManager.cs +++ b/mcs/class/System/System.Net/ServicePointManager.cs @@ -264,7 +264,6 @@ namespace System.Net throw new ArgumentException ("value"); maxServicePoints = value; - RecycleServicePoints (); } } @@ -329,9 +328,6 @@ namespace System.Net if (address == null) throw new ArgumentNullException ("address"); - if ((servicePoints.Count % 4) == 0) - RecycleServicePoints (); - var origAddress = new Uri (address.Scheme + "://" + address.Authority); bool usesProxy = false; @@ -378,41 +374,6 @@ namespace System.Net return sp; } - // Internal Methods - - static void RecycleServicePoints () - { - lock (servicePoints) { - var toRemove = new ArrayList (); - var idleList = new SortedDictionary<DateTime, ServicePoint> (); - IDictionaryEnumerator e = servicePoints.GetEnumerator (); - while (e.MoveNext ()) { - ServicePoint sp = (ServicePoint) e.Value; - DateTime idleSince; - if (sp.CheckAvailableForRecycling (out idleSince)) { - toRemove.Add (e.Key); - continue; - } - - while (idleList.ContainsKey (idleSince)) - idleSince = idleSince.AddMilliseconds (1); - idleList.Add (idleSince, sp); - } - - for (int i = 0; i < toRemove.Count; i++) - servicePoints.Remove (toRemove [i]); - - if (maxServicePoints == 0 || servicePoints.Count <= maxServicePoints) - return; - - // get rid of the ones with the longest idle time - foreach (var sp in idleList.Values) { - if (servicePoints.Count <= maxServicePoints) - break; - servicePoints.Remove (sp); - } - } - } #if SECURITY_DEP internal class ChainValidationHelper { object sender; diff --git a/mcs/class/System/System.Net/SimpleAsyncResult.cs b/mcs/class/System/System.Net/SimpleAsyncResult.cs new file mode 100644 index 0000000..f7c383b --- /dev/null +++ b/mcs/class/System/System.Net/SimpleAsyncResult.cs @@ -0,0 +1,220 @@ +// +// System.Net.WebAsyncResult +// +// Authors: +// Gonzalo Paniagua Javier (gonzalo@ximian.com) +// Martin Baulig (martin.baulig@xamarin.com) +// +// (C) 2003 Ximian, Inc (http://www.ximian.com) +// Copyright (c) 2014 Xamarin Inc. (http://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.IO; +using System.Threading; + +namespace System.Net +{ + delegate void SimpleAsyncCallback (SimpleAsyncResult result); + + delegate bool SimpleAsyncFunc (SimpleAsyncResult result); + + class SimpleAsyncResult : IAsyncResult + { + ManualResetEvent handle; + bool synch; + bool isCompleted; + SimpleAsyncCallback cb; + object state; + bool callbackDone; + Exception exc; + object locker = new object (); + + SimpleAsyncResult (SimpleAsyncCallback cb) + { + this.cb = cb; + } + + protected SimpleAsyncResult (AsyncCallback cb, object state) + { + this.state = state; + this.cb = result => { + if (cb != null) + cb (this); + }; + } + + public static SimpleAsyncResult Run (SimpleAsyncFunc func, SimpleAsyncCallback callback) + { + var result = new SimpleAsyncResult (callback); + try { + if (!func (result)) + result.SetCompleted (true); + } catch (Exception ex) { + result.SetCompleted (true, ex); + } + return result; + } + + public static SimpleAsyncResult RunWithLock (object locker, SimpleAsyncFunc func, SimpleAsyncCallback callback) + { + return Run (inner => { + bool running = func (inner); + if (running) + Monitor.Exit (locker); + return running; + }, inner => { + if (inner.GotException) { + if (inner.CompletedSynchronously) + Monitor.Exit (locker); + callback (inner); + return; + } + + try { + if (!inner.CompletedSynchronously) + Monitor.Enter (locker); + + callback (inner); + } finally { + Monitor.Exit (locker); + } + }); + } + + protected void Reset_internal () + { + callbackDone = false; + exc = null; + exc = null; + lock (locker) { + isCompleted = false; + if (handle != null) + handle.Reset (); + } + } + + internal void SetCompleted (bool synch, Exception e) + { + SetCompleted_internal (synch, e); + DoCallback_private (); + } + + internal void SetCompleted (bool synch) + { + SetCompleted_internal (synch); + DoCallback_private (); + } + + protected void SetCompleted_internal (bool synch, Exception e) + { + this.synch = synch; + exc = e; + lock (locker) { + isCompleted = true; + if (handle != null) + handle.Set (); + } + } + + protected void SetCompleted_internal (bool synch) + { + this.synch = synch; + exc = null; + lock (locker) { + isCompleted = true; + if (handle != null) + handle.Set (); + } + } + + void DoCallback_private () + { + if (callbackDone) + return; + callbackDone = true; + if (cb == null) + return; + cb (this); + } + + protected void DoCallback_internal () + { + if (!callbackDone && cb != null) { + callbackDone = true; + cb (this); + } + } + + internal void WaitUntilComplete () + { + if (IsCompleted) + return; + + AsyncWaitHandle.WaitOne (); + } + + internal bool WaitUntilComplete (int timeout, bool exitContext) + { + if (IsCompleted) + return true; + + return AsyncWaitHandle.WaitOne (timeout, exitContext); + } + + public object AsyncState { + get { return state; } + } + + public WaitHandle AsyncWaitHandle { + get { + lock (locker) { + if (handle == null) + handle = new ManualResetEvent (isCompleted); + } + + return handle; + } + } + + public bool CompletedSynchronously { + get { return synch; } + } + + public bool IsCompleted { + get { + lock (locker) { + return isCompleted; + } + } + } + + internal bool GotException { + get { return (exc != null); } + } + + internal Exception Exception { + get { return exc; } + } + } +} + diff --git a/mcs/class/System/System.Net/WebAsyncResult.cs b/mcs/class/System/System.Net/WebAsyncResult.cs index 7cc9d5e..4fc55d4 100644 --- a/mcs/class/System/System.Net/WebAsyncResult.cs +++ b/mcs/class/System/System.Net/WebAsyncResult.cs @@ -33,173 +33,67 @@ using System.Threading; namespace System.Net { - class WebAsyncResult : IAsyncResult + class WebAsyncResult : SimpleAsyncResult { - ManualResetEvent handle; - bool synch; - bool isCompleted; - AsyncCallback cb; - object state; int nbytes; IAsyncResult innerAsyncResult; - bool callbackDone; - Exception exc; HttpWebResponse response; Stream writeStream; byte [] buffer; int offset; int size; - object locker = new object (); public bool EndCalled; public bool AsyncWriteAll; public WebAsyncResult (AsyncCallback cb, object state) + : base (cb, state) { - this.cb = cb; - this.state = state; } public WebAsyncResult (HttpWebRequest request, AsyncCallback cb, object state) + : base (cb, state) { - this.cb = cb; - this.state = state; } public WebAsyncResult (AsyncCallback cb, object state, byte [] buffer, int offset, int size) + : base (cb, state) { - this.cb = cb; - this.state = state; this.buffer = buffer; this.offset = offset; this.size = size; } - internal void SetCompleted (bool synch, Exception e) - { - this.synch = synch; - exc = e; - lock (locker) { - isCompleted = true; - if (handle != null) - handle.Set (); - } - } - internal void Reset () { - callbackDone = false; - exc = null; - response = null; - writeStream = null; - exc = null; - lock (locker) { - isCompleted = false; - if (handle != null) - handle.Reset (); - } + this.nbytes = 0; + this.response = null; + this.buffer = null; + this.offset = 0; + this.size = 0; + Reset_internal (); } internal void SetCompleted (bool synch, int nbytes) { - this.synch = synch; this.nbytes = nbytes; - exc = null; - lock (locker) { - isCompleted = true; - if (handle != null) - handle.Set (); - } + SetCompleted_internal (synch); } internal void SetCompleted (bool synch, Stream writeStream) { - this.synch = synch; this.writeStream = writeStream; - exc = null; - lock (locker) { - isCompleted = true; - if (handle != null) - handle.Set (); - } + SetCompleted_internal (synch); } internal void SetCompleted (bool synch, HttpWebResponse response) { - this.synch = synch; this.response = response; - exc = null; - lock (locker) { - isCompleted = true; - if (handle != null) - handle.Set (); - } - } - - internal void DoCallback () - { - if (!callbackDone && cb != null) { - callbackDone = true; - if (synch) - cb (this); - else - ThreadPool.QueueUserWorkItem (CB, null); - } - } - - void CB (object unused) - { - cb (this); - } - - internal void WaitUntilComplete () - { - if (IsCompleted) - return; - - AsyncWaitHandle.WaitOne (); + SetCompleted_internal (synch); } - internal bool WaitUntilComplete (int timeout, bool exitContext) + internal void DoCallback () { - if (IsCompleted) - return true; - - return AsyncWaitHandle.WaitOne (timeout, exitContext); - } - - public object AsyncState { - get { return state; } - } - - public WaitHandle AsyncWaitHandle { - get { - lock (locker) { - if (handle == null) - handle = new ManualResetEvent (isCompleted); - } - - return handle; - } - } - - public bool CompletedSynchronously { - get { return synch; } - } - - public bool IsCompleted { - get { - lock (locker) { - return isCompleted; - } - } - } - - internal bool GotException { - get { return (exc != null); } - } - - internal Exception Exception { - get { return exc; } + DoCallback_internal (); } internal int NBytes { diff --git a/mcs/class/System/System.Net/WebConnectionGroup.cs b/mcs/class/System/System.Net/WebConnectionGroup.cs index 0348aee..5e14215 100644 --- a/mcs/class/System/System.Net/WebConnectionGroup.cs +++ b/mcs/class/System/System.Net/WebConnectionGroup.cs @@ -70,14 +70,16 @@ namespace System.Net //TODO: abort requests or wait for them to finish lock (sPoint) { closing = true; - foreach (var cnc in connections) { - if (cnc.Connection == null) - continue; - cnc.Connection.Close (false); - cnc.Connection = null; + var iter = connections.First; + while (iter != null) { + var cnc = iter.Value.Connection; + var node = iter; + iter = iter.Next; + + connections.Remove (node); + cnc.Close (false); OnConnectionClosed (); } - connections.Clear (); } } @@ -120,7 +122,7 @@ namespace System.Net ConnectionState FindIdleConnection () { foreach (var cnc in connections) { - if (cnc.Busy || cnc.Connection == null) + if (cnc.Busy) continue; connections.Remove (cnc); @@ -140,7 +142,7 @@ namespace System.Net return cnc.Connection; } - if (sPoint.ConnectionLimit > connections.Count) { + if (sPoint.ConnectionLimit > connections.Count || connections.Count == 0) { created = true; cnc = new ConnectionState (this); connections.AddFirst (cnc); @@ -177,14 +179,11 @@ namespace System.Net } int count = 0; - for (var node = connections.First; node != null; node = node.Next) { - var cnc = node.Value; - - if (cnc.Connection == null) { - connections.Remove (node); - OnConnectionClosed (); - continue; - } + var iter = connections.First; + while (iter != null) { + var cnc = iter.Value; + var node = iter; + iter = iter.Next; ++count; if (cnc.Busy) @@ -205,7 +204,7 @@ namespace System.Net if (connectionsToClose == null) connectionsToClose = new List<WebConnection> (); connectionsToClose.Add (cnc.Connection); - cnc.Connection = null; + connections.Remove (node); } recycled = connections.Count == 0; @@ -224,7 +223,10 @@ namespace System.Net } class ConnectionState : IWebConnectionState { - public WebConnection Connection; + public WebConnection Connection { + get; + private set; + } public WebConnectionGroup Group { get; diff --git a/mcs/class/System/System.Net/WebConnectionStream.cs b/mcs/class/System/System.Net/WebConnectionStream.cs index 5a34a3d..25c101a 100644 --- a/mcs/class/System/System.Net/WebConnectionStream.cs +++ b/mcs/class/System/System.Net/WebConnectionStream.cs @@ -633,10 +633,15 @@ namespace System.Net { } - internal WebAsyncResult SetHeadersAsync (bool setInternalLength, AsyncCallback callback, object state) + internal SimpleAsyncResult SetHeadersAsync (bool setInternalLength, SimpleAsyncCallback callback) + { + return SimpleAsyncResult.Run (r => SetHeadersAsync (r, setInternalLength), callback); + } + + bool SetHeadersAsync (SimpleAsyncResult result, bool setInternalLength) { if (headersSent) - return null; + return false; string method = request.Method; bool no_writestream = (method == "GET" || method == "CONNECT" || method == "HEAD" || @@ -648,59 +653,61 @@ namespace System.Net if (setInternalLength && !no_writestream && writeBuffer != null) request.InternalContentLength = writeBuffer.Length; - if (sendChunked || request.ContentLength > -1 || no_writestream || webdav) { - headersSent = true; - headers = request.GetRequestHeaders (); + if (!(sendChunked || request.ContentLength > -1 || no_writestream || webdav)) + return false; - var result = new WebAsyncResult (callback, state); - result.InnerAsyncResult = cnc.BeginWrite (request, headers, 0, headers.Length, new AsyncCallback (SetHeadersCB), result); - if (result.InnerAsyncResult != null) - return result; - } + headersSent = true; + headers = request.GetRequestHeaders (); - return null; - } - - void SetHeadersCB (IAsyncResult r) - { - WebAsyncResult result = (WebAsyncResult) r.AsyncState; - result.InnerAsyncResult = null; - try { - cnc.EndWrite (request, true, r); - result.SetCompleted (false, 0); - if (!initRead) { - initRead = true; - WebConnection.InitRead (cnc); + var innerResult = cnc.BeginWrite (request, headers, 0, headers.Length, r => { + try { + cnc.EndWrite (request, true, r); + if (!initRead) { + initRead = true; + WebConnection.InitRead (cnc); + } + var cl = request.ContentLength; + if (!sendChunked && cl == 0) + requestWritten = true; + result.SetCompleted (false); + } catch (WebException e) { + result.SetCompleted (false, e); + } catch (Exception e) { + result.SetCompleted (false, new WebException ("Error writing headers", e, WebExceptionStatus.SendFailure)); } - long cl = request.ContentLength; - if (!sendChunked && cl == 0) - requestWritten = true; - } catch (WebException e) { - result.SetCompleted (false, e); - } catch (Exception e) { - result.SetCompleted (false, new WebException ("Error writing headers", e, WebExceptionStatus.SendFailure)); - } - result.DoCallback (); + }, null); + + return innerResult != null; } internal bool RequestWritten { get { return requestWritten; } } - internal WebAsyncResult WriteRequestAsync (AsyncCallback callback, object state) + internal SimpleAsyncResult WriteRequestAsync (SimpleAsyncCallback callback) + { + var result = WriteRequestAsync (callback); + try { + if (!WriteRequestAsync (result)) + result.SetCompleted (true); + } catch (Exception ex) { + result.SetCompleted (true, ex); + } + return result; + } + + internal bool WriteRequestAsync (SimpleAsyncResult result) { if (requestWritten) - return null; + return false; requestWritten = true; - if (sendChunked) - return null; + if (sendChunked || !allowBuffering || writeBuffer == null) + return false; - if (!allowBuffering || writeBuffer == null) - return null; - - byte[] bytes = writeBuffer.GetBuffer (); - int length = (int)writeBuffer.Length; + // Keep the call for a potential side-effect of GetBuffer + var bytes = writeBuffer.GetBuffer (); + var length = (int)writeBuffer.Length; if (request.ContentLength != -1 && request.ContentLength < length) { nextReadCalled = true; cnc.Close (true); @@ -708,63 +715,39 @@ namespace System.Net WebExceptionStatus.ServerProtocolViolation, null); } - var result = new WebAsyncResult (callback, state); - result.InnerAsyncResult = SetHeadersAsync (true, WriteRequestAsyncCB, result); - if (result.InnerAsyncResult == null) - WriteRequestAsyncCB (result); - return result; - } - - void WriteRequestAsyncCB (IAsyncResult ar) - { - var result = (WebAsyncResult)ar; - var innerResult = (WebAsyncResult)result.InnerAsyncResult; - result.InnerAsyncResult = null; - - if (innerResult != null && innerResult.GotException) { - result.SetCompleted (false, innerResult.Exception); - result.DoCallback (); - return; - } - - if (cnc.Data.StatusCode != 0 && cnc.Data.StatusCode != 100) { - result.SetCompleted (false, 0); - result.DoCallback (); - return; - } - - byte[] bytes = writeBuffer.GetBuffer (); - int length = (int)writeBuffer.Length; + var ret = SetHeadersAsync (true, inner => { + if (inner.GotException) { + result.SetCompleted (inner.CompletedSynchronously, inner.Exception); + return; + } - if (length > 0) - result.InnerAsyncResult = cnc.BeginWrite (request, bytes, 0, length, WriteRequestAsyncCB2, result); + if (cnc.Data.StatusCode != 0 && cnc.Data.StatusCode != 100) { + result.SetCompleted (inner.CompletedSynchronously); + return; + } - if (!initRead) { - initRead = true; - WebConnection.InitRead (cnc); - } + if (!initRead) { + initRead = true; + WebConnection.InitRead (cnc); + } - if (length == 0) { - result.SetCompleted (false, 0); - result.DoCallback (); - complete_request_written = true; - } - } + if (length == 0) { + complete_request_written = true; + result.SetCompleted (inner.CompletedSynchronously); + return; + } - void WriteRequestAsyncCB2 (IAsyncResult ar) - { - var result = (WebAsyncResult)ar.AsyncState; - var innerResult = result.InnerAsyncResult; - result.InnerAsyncResult = null; + cnc.BeginWrite (request, bytes, 0, length, r => { + try { + complete_request_written = cnc.EndWrite (request, false, r); + result.SetCompleted (false); + } catch (Exception exc) { + result.SetCompleted (false, exc); + } + }, null); + }); - try { - complete_request_written = cnc.EndWrite (request, false, innerResult); - result.SetCompleted (false, 0); - } catch (Exception exc) { - result.SetCompleted (false, exc); - } finally { - result.DoCallback (); - } + return true; } internal void InternalClose () diff --git a/mcs/class/System/System.dll.sources b/mcs/class/System/System.dll.sources index 55cb9d9..55e98bb 100644 --- a/mcs/class/System/System.dll.sources +++ b/mcs/class/System/System.dll.sources @@ -834,6 +834,7 @@ System.Net.Security/SslPolicyErrors.cs System.Net/ServicePoint.cs System.Net/ServicePointManager.cs System.Net/ServicePointManager.extra.cs +System.Net/SimpleAsyncResult.cs System.Net/SocketAddress.cs System.Net/SocketPermissionAttribute.cs System.Net/SocketPermission.cs diff --git a/mcs/class/System/mobile_System.dll.sources b/mcs/class/System/mobile_System.dll.sources index cf329b6..a90a333 100644 --- a/mcs/class/System/mobile_System.dll.sources +++ b/mcs/class/System/mobile_System.dll.sources @@ -526,6 +526,7 @@ System.Net/SecurityProtocolType.cs System.Net/ServicePoint.cs System.Net/ServicePointManager.cs System.Net/ServicePointManager.extra.cs +System.Net/SimpleAsyncResult.cs System.Net/SocketAddress.cs System.Net/TransportContext.cs System.Net/TransportType.cs diff --git a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/LightCompiler.cs b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/LightCompiler.cs index 61a0974..f59fb87 100644 --- a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/LightCompiler.cs +++ b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/LightCompiler.cs @@ -698,16 +698,12 @@ namespace Microsoft.Scripting.Interpreter { typeTo = TypeUtils.GetNonNullableType (typeTo); var nullValue = _instructions.MakeLabel(); - var end = _instructions.MakeLabel(); _instructions.EmitDup (); _instructions.EmitBranchNull(nullValue); CompileConvertToType (typeFrom, typeTo, isChecked); _instructions.EmitWrap (typeTo); - _instructions.EmitBranch (end); _instructions.MarkLabel(nullValue); - _instructions.EmitDup (); // Keep null on the stack - _instructions.MarkLabel(end); return; } diff --git a/mono/io-layer/processes.c b/mono/io-layer/processes.c index 3c8f7f1..a974a64 100644 --- a/mono/io-layer/processes.c +++ b/mono/io-layer/processes.c @@ -1642,15 +1642,12 @@ gboolean GetProcessTimes (gpointer process, WapiFileTime *create_time, if (process_handle->id == getpid ()) { struct rusage time_data; if (getrusage (RUSAGE_SELF, &time_data) == 0) { - gint64 tick_val; - gint64 *tick_val_ptr; + guint64 tick_val; ku_times_set = TRUE; - tick_val = time_data.ru_utime.tv_sec * 10000000 + time_data.ru_utime.tv_usec * 10; - tick_val_ptr = (gint64*)user_time; - *tick_val_ptr = tick_val; - tick_val = time_data.ru_stime.tv_sec * 10000000 + time_data.ru_stime.tv_usec * 10; - tick_val_ptr = (gint64*)kernel_time; - *tick_val_ptr = tick_val; + tick_val = (guint64)time_data.ru_utime.tv_sec * 10000000 + (guint64)time_data.ru_utime.tv_usec * 10; + _wapi_guint64_to_filetime (tick_val, user_time); + tick_val = (guint64)time_data.ru_stime.tv_sec * 10000000 + (guint64)time_data.ru_stime.tv_usec * 10; + _wapi_guint64_to_filetime (tick_val, kernel_time); } } #endif diff --git a/mono/io-layer/timefuncs-private.h b/mono/io-layer/timefuncs-private.h index 64c6dbb..a4029a9 100644 --- a/mono/io-layer/timefuncs-private.h +++ b/mono/io-layer/timefuncs-private.h @@ -17,5 +17,6 @@ extern void _wapi_time_t_to_filetime (time_t timeval, WapiFileTime *filetime); extern void _wapi_timeval_to_filetime (struct timeval *tv, WapiFileTime *filetime); +extern void _wapi_guint64_to_filetime (guint64 ticks, WapiFileTime *filetime); #endif /* _WAPI_TIMEFUNCS_PRIVATE_H_ */ diff --git a/mono/io-layer/timefuncs.c b/mono/io-layer/timefuncs.c index 16d01f8..8a79f3b 100644 --- a/mono/io-layer/timefuncs.c +++ b/mono/io-layer/timefuncs.c @@ -38,6 +38,12 @@ void _wapi_timeval_to_filetime (struct timeval *tv, WapiFileTime *filetime) filetime->dwHighDateTime = ticks >> 32; } +void _wapi_guint64_to_filetime (guint64 ticks, WapiFileTime *filetime) +{ + filetime->dwLowDateTime = ticks & 0xFFFFFFFF; + filetime->dwHighDateTime = ticks >> 32; +} + gboolean QueryPerformanceCounter(WapiLargeInteger *count G_GNUC_UNUSED) { return(FALSE); diff --git a/mono/metadata/process.c b/mono/metadata/process.c index 0820433..658c433 100755 --- a/mono/metadata/process.c +++ b/mono/metadata/process.c @@ -814,44 +814,40 @@ MonoBoolean ves_icall_System_Diagnostics_Process_WaitForInputIdle_internal (Mono return (ret) ? FALSE : TRUE; } +static guint64 +file_time_to_guint64 (FILETIME *time) +{ + return ((guint64)time->dwHighDateTime << 32) | ((guint64)time->dwLowDateTime); +} + gint64 ves_icall_System_Diagnostics_Process_ExitTime_internal (HANDLE process) { gboolean ret; - gint64 ticks; FILETIME create_time, exit_time, kernel_time, user_time; MONO_ARCH_SAVE_REGS; - ret=GetProcessTimes (process, &create_time, &exit_time, &kernel_time, - &user_time); - if(ret==TRUE) { - ticks=((guint64)exit_time.dwHighDateTime << 32) + - exit_time.dwLowDateTime; - - return(ticks); - } else { - return(0); - } + ret = GetProcessTimes (process, &create_time, &exit_time, &kernel_time, + &user_time); + if (ret) + return file_time_to_guint64 (&exit_time); + else + return 0; } gint64 ves_icall_System_Diagnostics_Process_StartTime_internal (HANDLE process) { gboolean ret; - gint64 ticks; FILETIME create_time, exit_time, kernel_time, user_time; MONO_ARCH_SAVE_REGS; - ret=GetProcessTimes (process, &create_time, &exit_time, &kernel_time, - &user_time); - if(ret==TRUE) { - ticks=((guint64)create_time.dwHighDateTime << 32) + - create_time.dwLowDateTime; - - return(ticks); - } else { - return(0); - } + ret = GetProcessTimes (process, &create_time, &exit_time, &kernel_time, + &user_time); + if (ret) + return file_time_to_guint64 (&create_time); + else + return 0; } gint32 ves_icall_System_Diagnostics_Process_ExitCode_internal (HANDLE process) @@ -989,12 +985,15 @@ ves_icall_System_Diagnostics_Process_Times (HANDLE process, gint32 type) FILETIME create_time, exit_time, kernel_time, user_time; if (GetProcessTimes (process, &create_time, &exit_time, &kernel_time, &user_time)) { + guint64 ktime = file_time_to_guint64 (&kernel_time); + guint64 utime = file_time_to_guint64 (&user_time); + if (type == 0) - return *(gint64*)&user_time; + return utime; else if (type == 1) - return *(gint64*)&kernel_time; - /* system + user time: FILETIME can be (memory) cast to a 64 bit int */ - return *(gint64*)&kernel_time + *(gint64*)&user_time; + return ktime; + else + return ktime + utime; } return 0; }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor