Imported Upstream version 4.4.0.40

Former-commit-id: 6427cc082e74df30afc535fd906a3494b74b0817
This commit is contained in:
Xamarin Public Jenkins 2016-03-16 12:38:19 -04:00
parent f3e3aab35a
commit a632333cc7
110 changed files with 1496 additions and 556 deletions

View File

@ -84,8 +84,8 @@ DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/configure $(am__configure_deps) \
$(srcdir)/config.h.in mkinstalldirs \
$(srcdir)/mono-uninstalled.pc.in COPYING.LIB ChangeLog NEWS \
compile config.guess config.rpath config.sub install-sh \
missing ltmain.sh
compile config.guess config.rpath config.sub depcomp \
install-sh missing ltmain.sh
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/iconv.m4 \
$(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \

View File

@ -1 +1 @@
79ba3854a41b122e90badfb88a8aba24b6abc54c
25ac5dd52e897440dac529dfcfe2034bdae89d53

View File

@ -1 +1 @@
568cb227ed520bd10d312bf4a66ccba0f772b016
3decb1ccc1162ebbe9663424f20f2ace97e2921f

View File

@ -293,8 +293,10 @@ namespace System.Diagnostics {
internal void WaitUtilEOF() {
if( eofEvent != null) {
eofEvent.WaitOne();
#if !MONO
eofEvent.Close();
eofEvent = null;
#endif
}
}
}

View File

@ -142,6 +142,11 @@ instead of going through the operating system symbol lookup operation.
.I llvm-path=<PREFIX>
Same for the llvm tools 'opt' and 'llc'.
.TP
.I gen-seq-points-file=FILE.msym
Instructs the AOT compiler to generate offline sequence points .msym files.
The path is optional, if none is passed then a .msym file will be generated
next to the input assembly.
.TP
.I mtriple=<TRIPLE>
Use the GNU style target triple <TRIPLE> to determine some code generation options, i.e.
--mtriple=armv7-linux-gnueabi will generate code that targets ARMv7. This is currently

View File

@ -34,7 +34,7 @@ static class Consts
// Use these assembly version constants to make code more maintainable.
//
public const string MonoVersion = "4.3.2.0";
public const string MonoVersion = "4.4.0.0";
public const string MonoCompany = "Mono development team";
public const string MonoProduct = "Mono Common Language Infrastructure";
public const string MonoCopyright = "(c) Various Mono authors";

View File

@ -153,7 +153,7 @@ namespace Microsoft.Build.Tasks
throw;
}
Log.LogErrorWithCodeFromResources ("XmlPeek.ArgumentError", e.Message);
Log.LogError ("MSB3741: Unable to load arguments for the XmlPeek task. {0}", e.Message);
return false;
}
@ -169,7 +169,7 @@ namespace Microsoft.Build.Tasks
throw;
}
Log.LogErrorWithCodeFromResources ("XmlPeekPoke.InputFileError", _xmlInputPath.ItemSpec, e.Message);
Log.LogError ("MSB3733: Input file \"{0}\" cannot be opened. {1}", _xmlInputPath.ItemSpec, e.Message);
return false;
} finally {
xmlinput.CloseReader ();
@ -185,7 +185,7 @@ namespace Microsoft.Build.Tasks
throw;
}
Log.LogErrorWithCodeFromResources ("XmlPeekPoke.XPathError", _query, e.Message);
Log.LogError ("MSB3734: XPath Query \"{0}\" cannot be loaded. {1}", _query, e.Message);
return false;
}
@ -199,14 +199,14 @@ namespace Microsoft.Build.Tasks
throw;
}
Log.LogErrorWithCodeFromResources ("XmlPeek.NamespacesError", e.Message);
Log.LogError ("MSB3742: Unable to process the Namespaces argument for the XmlPeek task. {0}", e.Message);
return false;
}
try {
expr.SetContext (xmlNamespaceManager);
} catch (XPathException e) {
Log.LogErrorWithCodeFromResources ("XmlPeek.XPathContextError", e.Message);
Log.LogError ("MSB3743: Unable to set XPath expression's Context. {0}", e.Message);
return false;
}
@ -228,12 +228,12 @@ namespace Microsoft.Build.Tasks
_result [i++] = new TaskItem (item);
// This can be logged a lot, so low importance
Log.LogMessageFromResources (MessageImportance.Low, "XmlPeek.Found", item);
Log.LogMessage (MessageImportance.Low, "Found \"{0}\".", item);
}
if (_result.Length == 0) {
// Logged no more than once per execute of this task
Log.LogMessageFromResources ("XmlPeek.NotFound");
Log.LogMessage ("The specified XPath query did not capture any nodes.");
}
return true;

View File

@ -21,5 +21,5 @@ EXTRA_DISTFILES = Mono.Security.Interface/README.md
#
# Update this comment to trigger a build in System
# +1
# +2
#

View File

@ -49,7 +49,7 @@ namespace Mono.Security.Interface
set { checkCertRevocationStatus = value; }
}
public bool UseServicePointManagerCallback {
public bool? UseServicePointManagerCallback {
get { return useServicePointManagerCallback; }
set { useServicePointManagerCallback = value; }
}
@ -89,7 +89,7 @@ namespace Mono.Security.Interface
bool cloned = false;
bool checkCertName = true;
bool checkCertRevocationStatus = false;
bool useServicePointManagerCallback = true;
bool? useServicePointManagerCallback = null;
bool skipSystemValidators = false;
bool callbackNeedsChain = true;
ICertificateValidator certificateValidator;

View File

@ -127,6 +127,8 @@ namespace Mono.Security.X509 {
CheckStore (_storePath, true);
string filename = Path.Combine (_storePath, GetUniqueName (certificate));
if (!File.Exists (filename)) {
filename = Path.Combine (_storePath, GetUniqueNameWithSerial (certificate));
if (!File.Exists (filename)) {
using (FileStream fs = File.Create (filename)) {
byte[] data = certificate.RawData;
@ -135,6 +137,17 @@ namespace Mono.Security.X509 {
}
ClearCertificates (); // We have modified the store on disk. So forget the old state.
}
} else {
string newfilename = Path.Combine (_storePath, GetUniqueNameWithSerial (certificate));
if (GetUniqueNameWithSerial (LoadCertificate (filename)) != GetUniqueNameWithSerial (certificate)) {
using (FileStream fs = File.Create (newfilename)) {
byte[] data = certificate.RawData;
fs.Write (data, 0, data.Length);
fs.Close ();
}
ClearCertificates (); // We have modified the store on disk. So forget the old state.
}
}
#if !NET_2_1
// Try to save privateKey if available..
CspParameters cspParams = new CspParameters ();
@ -164,10 +177,16 @@ namespace Mono.Security.X509 {
public void Remove (X509Certificate certificate)
{
string filename = Path.Combine (_storePath, GetUniqueName (certificate));
string filename = Path.Combine (_storePath, GetUniqueNameWithSerial (certificate));
if (File.Exists (filename)) {
File.Delete (filename);
ClearCertificates (); // We have modified the store on disk. So forget the old state.
} else {
filename = Path.Combine (_storePath, GetUniqueName (certificate));
if (File.Exists (filename)) {
File.Delete (filename);
ClearCertificates (); // We have modified the store on disk. So forget the old state.
}
}
}
@ -182,10 +201,15 @@ namespace Mono.Security.X509 {
// private stuff
private string GetUniqueName (X509Certificate certificate)
private string GetUniqueNameWithSerial (X509Certificate certificate)
{
return GetUniqueName (certificate, certificate.SerialNumber);
}
private string GetUniqueName (X509Certificate certificate, byte[] serial = null)
{
string method;
byte[] name = GetUniqueName (certificate.Extensions);
byte[] name = GetUniqueName (certificate.Extensions, serial);
if (name == null) {
method = "tbp"; // thumbprint
name = certificate.Hash;
@ -208,7 +232,7 @@ namespace Mono.Security.X509 {
return GetUniqueName (method, name, ".crl");
}
private byte[] GetUniqueName (X509ExtensionCollection extensions)
private byte[] GetUniqueName (X509ExtensionCollection extensions, byte[] serial = null)
{
// We prefer Subject Key Identifier as the unique name
// as it will provide faster lookups
@ -217,7 +241,14 @@ namespace Mono.Security.X509 {
return null;
SubjectKeyIdentifierExtension ski = new SubjectKeyIdentifierExtension (ext);
if (serial == null) {
return ski.Identifier;
} else {
byte[] uniqueWithSerial = new byte[ski.Identifier.Length + serial.Length];
System.Buffer.BlockCopy (ski.Identifier, 0, uniqueWithSerial, 0, ski.Identifier.Length );
System.Buffer.BlockCopy (serial, 0, uniqueWithSerial, ski.Identifier.Length, serial.Length );
return uniqueWithSerial;
}
}
private string GetUniqueName (string method, byte[] name, string fileExtension)

View File

@ -22,7 +22,7 @@ namespace SharpCompress.Writer.Zip
byte[] encodedFilename = Encoding.UTF8.GetBytes(FileName);
byte[] encodedComment = Encoding.UTF8.GetBytes(Comment);
outputStream.Write(new byte[] {80, 75, 1, 2, 0x3F, 0, 0x0A, 0}, 0, 8);
outputStream.Write(new byte[] {80, 75, 1, 2, 0x14, 0, 0x0A, 0}, 0, 8);
HeaderFlags flags = HeaderFlags.UTF8;
if (!outputStream.CanSeek)
{

View File

@ -142,7 +142,7 @@ namespace SharpCompress.Writer.Zip
byte[] encodedFilename = encoding.GetBytes(filename);
OutputStream.Write(BitConverter.GetBytes(ZipHeaderFactory.ENTRY_HEADER_BYTES), 0, 4);
OutputStream.Write(new byte[] {63, 0}, 0, 2); //version
OutputStream.Write(new byte[] {20, 0}, 0, 2); //version
HeaderFlags flags = encoding == Encoding.UTF8 ? HeaderFlags.UTF8 : (HeaderFlags)0;
if (!OutputStream.CanSeek)
{

View File

@ -114,6 +114,51 @@ namespace MonoTests.System.IO.Compression
File.Delete ("test.zip");
}
[Test]
public void ZipOpenAndReopenEntry()
{
try {
File.Copy("archive.zip", "test.zip", overwrite: true);
using (var archive = new ZipArchive(File.Open("test.zip", FileMode.Open),
ZipArchiveMode.Update))
{
var entry = archive.GetEntry("foo.txt");
Assert.IsNotNull(entry);
var stream = entry.Open();
try {
stream = entry.Open();
} catch (global::System.IO.IOException ex) {
return;
}
Assert.Fail();
}
} finally {
File.Delete ("test.zip");
}
}
[Test]
public void ZipOpenCloseAndReopenEntry()
{
File.Copy("archive.zip", "test.zip", overwrite: true);
using (var archive = new ZipArchive(File.Open("test.zip", FileMode.Open),
ZipArchiveMode.Update))
{
var entry = archive.GetEntry("foo.txt");
Assert.IsNotNull(entry);
var stream = entry.Open();
stream.Dispose();
stream = entry.Open();
}
File.Delete ("test.zip");
}
[Test]
public void ZipGetEntryDeleteReadMode()
{

View File

@ -29,10 +29,96 @@ using SharpCompress.Archive;
namespace System.IO.Compression
{
internal class ZipArchiveEntryStream : Stream, IDisposable
{
private readonly ZipArchiveEntry entry;
private readonly Stream stream;
public override bool CanRead {
get {
return stream.CanRead;
}
}
public override bool CanSeek {
get {
return stream.CanSeek;
}
}
public override bool CanWrite {
get {
return stream.CanWrite;
}
}
public override long Length {
get {
return stream.Length;
}
}
public override long Position {
get {
return stream.Position;
}
set {
stream.Position = value;
}
}
public ZipArchiveEntryStream(ZipArchiveEntry entry, Stream stream)
{
this.entry = entry;
this.stream = stream;
}
public override void Flush ()
{
stream.Flush();
}
public override long Seek (long offset, SeekOrigin origin)
{
return stream.Seek(offset, origin);
}
public override void SetLength (long value)
{
stream.SetLength(value);
}
public override int Read (byte[] buffer, int offset, int count)
{
return stream.Read(buffer, offset, count);
}
public override void Write (byte[] buffer, int offset, int count)
{
stream.Write(buffer, offset, count);
}
public new void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
base.Dispose();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
entry.openStream = null;
stream.Dispose();
}
}
}
public class ZipArchiveEntry
{
readonly SharpCompress.Archive.Zip.ZipArchiveEntry entry;
private Stream openStream;
internal ZipArchiveEntryStream openStream;
private bool wasDeleted;
internal ZipArchiveEntry(ZipArchive archive, SharpCompress.Archive.Zip.ZipArchiveEntry entry)
@ -112,7 +198,7 @@ namespace System.IO.Compression
if (Archive.Mode == ZipArchiveMode.Create && openStream != null)
throw new IOException("The archive for this entry was opened with the Create mode, and this entry has already been written to.");
openStream = entry.OpenEntryStream();
openStream = new ZipArchiveEntryStream(this, entry.OpenEntryStream());
return openStream;
}

View File

@ -442,7 +442,7 @@ namespace System.Json
{
if (value == null)
throw new ArgumentNullException ("value");
return Convert.ToUInt16 (((JsonPrimitive) value).Value, NumberFormatInfo.InvariantInfo);
return Convert.ToUInt32 (((JsonPrimitive) value).Value, NumberFormatInfo.InvariantInfo);
}
public static implicit operator ulong (JsonValue value)

View File

@ -112,6 +112,30 @@ namespace MonoTests.System
Assert.AreEqual (number, jvalue); // should be exactly the same
}
[Test]
public void CheckIntegers ()
{
Assert.AreEqual (sbyte.MinValue, (sbyte) JsonValue.Parse (new JsonPrimitive (sbyte.MinValue).ToString ()));
Assert.AreEqual (sbyte.MaxValue, (sbyte) JsonValue.Parse (new JsonPrimitive (sbyte.MaxValue).ToString ()));
Assert.AreEqual (byte.MinValue, (byte) JsonValue.Parse (new JsonPrimitive (byte.MinValue).ToString ()));
Assert.AreEqual (byte.MaxValue, (byte) JsonValue.Parse (new JsonPrimitive (byte.MaxValue).ToString ()));
Assert.AreEqual (short.MinValue, (short) JsonValue.Parse (new JsonPrimitive (short.MinValue).ToString ()));
Assert.AreEqual (short.MaxValue, (short) JsonValue.Parse (new JsonPrimitive (short.MaxValue).ToString ()));
Assert.AreEqual (ushort.MinValue, (ushort) JsonValue.Parse (new JsonPrimitive (ushort.MinValue).ToString ()));
Assert.AreEqual (ushort.MaxValue, (ushort) JsonValue.Parse (new JsonPrimitive (ushort.MaxValue).ToString ()));
Assert.AreEqual (int.MinValue, (int) JsonValue.Parse (new JsonPrimitive (int.MinValue).ToString ()));
Assert.AreEqual (int.MaxValue, (int) JsonValue.Parse (new JsonPrimitive (int.MaxValue).ToString ()));
Assert.AreEqual (uint.MinValue, (uint) JsonValue.Parse (new JsonPrimitive (uint.MinValue).ToString ()));
Assert.AreEqual (uint.MaxValue, (uint) JsonValue.Parse (new JsonPrimitive (uint.MaxValue).ToString ()));
Assert.AreEqual (long.MinValue, (long) JsonValue.Parse (new JsonPrimitive (long.MinValue).ToString ()));
Assert.AreEqual (long.MaxValue, (long) JsonValue.Parse (new JsonPrimitive (long.MaxValue).ToString ()));
Assert.AreEqual (ulong.MinValue, (ulong) JsonValue.Parse (new JsonPrimitive (ulong.MinValue).ToString ()));
Assert.AreEqual (ulong.MaxValue, (ulong) JsonValue.Parse (new JsonPrimitive (ulong.MaxValue).ToString ()));
}
[Test]
public void CheckNumbers ()
{
@ -262,3 +286,10 @@ namespace MonoTests.System
}
}
}
// vim: noexpandtab
// Local Variables:
// tab-width: 4
// c-basic-offset: 4
// indent-tabs-mode: t
// End:

View File

@ -0,0 +1 @@
#include System.Net.Http.dll.sources

View File

@ -0,0 +1 @@
#include System.Net.Http.dll.sources

View File

@ -237,24 +237,30 @@ namespace Mono.Security.Cryptography {
private static RSA user;
private static RSA machine;
private readonly static object user_lock = new object ();
private readonly static object machine_lock = new object ();
private static RSA GetKey (DataProtectionScope scope)
{
switch (scope) {
case DataProtectionScope.CurrentUser:
if (user == null) {
lock (user_lock) {
CspParameters csp = new CspParameters ();
csp.KeyContainerName = "DAPI";
user = new RSACryptoServiceProvider (1536, csp);
}
}
return user;
case DataProtectionScope.LocalMachine:
if (machine == null) {
lock (machine_lock) {
CspParameters csp = new CspParameters ();
csp.KeyContainerName = "DAPI";
csp.Flags = CspProviderFlags.UseMachineKeyStore;
machine = new RSACryptoServiceProvider (1536, csp);
}
}
return machine;
default:
throw new CryptographicException (Locale.GetText ("Invalid scope."));

View File

@ -12,6 +12,9 @@
using NUnit.Framework;
using System;
using System.Text;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Security.Cryptography;
namespace MonoTests.System.Security.Cryptography {
@ -64,6 +67,31 @@ namespace MonoTests.System.Security.Cryptography {
ProtectUnprotect (notMuchEntropy, DataProtectionScope.LocalMachine);
}
[Test] // https://bugzilla.xamarin.com/show_bug.cgi?id=38933
public void ProtectCurrentUserMultiThread ()
{
string data = "Hello World";
string entropy = "This is a long string with no meaningful content.";
var entropyBytes = Encoding.UTF8.GetBytes (entropy);
var dataBytes = Encoding.UTF8.GetBytes (data);
var tasks = new List<Task> ();
for (int i = 0; i < 20; i++)
{
tasks.Add (new Task (() => {
byte[] encryptedBytes = ProtectedData.Protect (dataBytes, entropyBytes, DataProtectionScope.CurrentUser);
Assert.IsFalse (IsEmpty (encryptedBytes), "#1");
byte[] decryptedBytes = ProtectedData.Unprotect (encryptedBytes, entropyBytes, DataProtectionScope.CurrentUser);
string decryptedString = Encoding.UTF8.GetString(decryptedBytes);
Assert.AreEqual (data, decryptedString, "#2");
}, TaskCreationOptions.LongRunning));
}
foreach (var t in tasks) t.Start ();
Task.WaitAll (tasks.ToArray ());
}
[Test]
public void DataProtectionScope_All ()
{

View File

@ -160,7 +160,7 @@ namespace Mono.Net.Security
certValidationCallback = new ServerCertValidationCallback (callback);
}
certSelectionCallback = Private.CallbackHelpers.MonoToInternal (settings.ClientCertificateSelectionCallback);
fallbackToSPM = settings.UseServicePointManagerCallback;
fallbackToSPM = settings.UseServicePointManagerCallback ?? stream != null;
}
if (stream != null) {
@ -264,7 +264,7 @@ namespace Mono.Net.Security
leaf = certs [0];
if (tlsStream != null)
request.ServicePoint.SetServerCertificate (leaf);
request.ServicePoint.UpdateServerCertificate (leaf);
if (leaf == null) {
errors |= SslPolicyErrors.RemoteCertificateNotAvailable;

View File

@ -109,14 +109,20 @@ namespace Mono.Net.Security
ServicePointManager.CheckCertificateRevocationList);
status = WebExceptionStatus.Success;
} catch (Exception ex) {
status = WebExceptionStatus.SecureChannelFailure;
throw;
} finally {
if (CertificateValidationFailed)
status = WebExceptionStatus.TrustFailure;
request.ServicePoint.SetClientCertificate (sslStream.InternalLocalCertificate);
if (status != WebExceptionStatus.Success)
if (status == WebExceptionStatus.Success)
request.ServicePoint.UpdateClientCertificate (sslStream.InternalLocalCertificate);
else {
request.ServicePoint.UpdateClientCertificate (null);
sslStream = null;
}
}
try {
if (buffer != null)

View File

@ -74,7 +74,7 @@ namespace System.Diagnostics {
public bool LoadUserProfile;
};
IntPtr process_handle;
SafeProcessHandle process_handle;
int pid;
int enable_raising_events;
Thread background_wait_for_exit_thread;
@ -82,13 +82,14 @@ namespace System.Diagnostics {
EventHandler exited_event;
/* Private constructor called from other methods */
private Process(IntPtr handle, int id) {
private Process (SafeProcessHandle handle, int id) {
process_handle = handle;
pid=id;
}
public Process ()
{
process_handle = new SafeProcessHandle ();
}
[MonoTODO]
@ -117,14 +118,21 @@ namespace System.Diagnostics {
[MonitoringDescription ("The exit code of the process.")]
public int ExitCode {
get {
if (process_handle == IntPtr.Zero)
if (process_handle.IsInvalid)
throw new InvalidOperationException ("Process has not been started.");
int code = ExitCode_internal (process_handle);
bool release = false;
try {
process_handle.DangerousAddRef (ref release);
int code = ExitCode_internal (process_handle.DangerousGetHandle ());
if (code == 259)
throw new InvalidOperationException ("The process must exit before getting the requested information.");
return code;
} finally {
if (release)
process_handle.DangerousRelease ();
}
}
}
@ -138,14 +146,21 @@ namespace System.Diagnostics {
[MonitoringDescription ("The exit time of the process.")]
public DateTime ExitTime {
get {
if (process_handle == IntPtr.Zero)
if (process_handle.IsInvalid)
throw new InvalidOperationException ("Process has not been started.");
if (!HasExited)
throw new InvalidOperationException ("The process must exit before " +
"getting the requested information.");
return(DateTime.FromFileTime(ExitTime_internal(process_handle)));
bool release = false;
try {
process_handle.DangerousAddRef (ref release);
return(DateTime.FromFileTime(ExitTime_internal(process_handle.DangerousGetHandle ())));
} finally {
if (release)
process_handle.DangerousRelease ();
}
}
}
@ -153,9 +168,9 @@ namespace System.Diagnostics {
[MonitoringDescription ("Handle for this process.")]
public IntPtr Handle {
get {
if (process_handle == IntPtr.Zero)
if (process_handle.IsInvalid)
throw new InvalidOperationException ("No process is associated with this object.");
return(process_handle);
return process_handle.DangerousGetHandle ();
}
}
@ -172,16 +187,18 @@ namespace System.Diagnostics {
[MonitoringDescription ("Determines if the process is still running.")]
public bool HasExited {
get {
if (process_handle == IntPtr.Zero)
if (process_handle.IsInvalid)
throw new InvalidOperationException ("Process has not been started.");
int exitcode = ExitCode_internal (process_handle);
bool release = false;
try {
process_handle.DangerousAddRef (ref release);
if(exitcode==259) {
/* STILL_ACTIVE */
return(false);
} else {
return(true);
/* STILL_ACTIVE = 259 */
return ExitCode_internal (process_handle.DangerousGetHandle ()) != 259;
} finally {
if (release)
process_handle.DangerousRelease ();
}
}
}
@ -247,23 +264,33 @@ namespace System.Diagnostics {
"The process " + ProcessName +
" (ID " + Id + ") has exited");
int min;
int max;
bool ok=GetWorkingSet_internal(process_handle, out min, out max);
if(ok==false) {
bool release = false;
try {
process_handle.DangerousAddRef (ref release);
int min, max;
if (!GetWorkingSet_internal(process_handle.DangerousGetHandle (), out min, out max))
throw new Win32Exception();
}
return((IntPtr)max);
} finally {
if (release)
process_handle.DangerousRelease ();
}
}
set {
if(HasExited) {
throw new InvalidOperationException("The process " + ProcessName + " (ID " + Id + ") has exited");
}
bool ok=SetWorkingSet_internal(process_handle, 0, value.ToInt32(), false);
if(ok==false) {
bool release = false;
try {
process_handle.DangerousAddRef (ref release);
if(!SetWorkingSet_internal (process_handle.DangerousGetHandle (), 0, value.ToInt32(), false))
throw new Win32Exception();
} finally {
if (release)
process_handle.DangerousRelease ();
}
}
}
@ -277,12 +304,19 @@ namespace System.Diagnostics {
"The process " + ProcessName +
" (ID " + Id + ") has exited");
int min;
int max;
bool ok= GetWorkingSet_internal (process_handle, out min, out max);
if(!ok)
bool release = false;
try {
process_handle.DangerousAddRef (ref release);
int min, max;
if(!GetWorkingSet_internal (process_handle.DangerousGetHandle (), out min, out max))
throw new Win32Exception();
return ((IntPtr) min);
} finally {
if (release)
process_handle.DangerousRelease ();
}
}
set {
if(HasExited)
@ -290,9 +324,16 @@ namespace System.Diagnostics {
"The process " + ProcessName +
" (ID " + Id + ") has exited");
bool ok = SetWorkingSet_internal (process_handle, value.ToInt32(), 0, true);
if (!ok)
bool release = false;
try {
process_handle.DangerousAddRef (ref release);
if (!SetWorkingSet_internal (process_handle.DangerousGetHandle (), value.ToInt32(), 0, true))
throw new Win32Exception();
} finally {
if (release)
process_handle.DangerousRelease ();
}
}
}
@ -310,7 +351,7 @@ namespace System.Diagnostics {
get {
if (module_collection == null)
module_collection = new ProcessModuleCollection(
GetModules_internal (process_handle));
GetModules_internal (process_handle.DangerousGetHandle ()));
return(module_collection);
}
}
@ -452,14 +493,24 @@ namespace System.Diagnostics {
[MonitoringDescription ("The relative process priority.")]
public ProcessPriorityClass PriorityClass {
get {
if (process_handle == IntPtr.Zero)
if (process_handle.IsInvalid)
throw new InvalidOperationException ("Process has not been started.");
bool release = false;
try {
process_handle.DangerousAddRef (ref release);
int error;
int prio = GetPriorityClass (process_handle, out error);
int prio = GetPriorityClass (process_handle.DangerousGetHandle (), out error);
if (prio == 0)
throw new Win32Exception (error);
return (ProcessPriorityClass) prio;
} finally {
if (release)
process_handle.DangerousRelease ();
}
}
set {
if (!Enum.IsDefined (typeof (ProcessPriorityClass), value))
@ -467,20 +518,25 @@ namespace System.Diagnostics {
"value", (int) value,
typeof (ProcessPriorityClass));
if (process_handle == IntPtr.Zero)
if (process_handle.IsInvalid)
throw new InvalidOperationException ("Process has not been started.");
int error;
if (!SetPriorityClass (process_handle, (int) value, out error)) {
CheckExited ();
throw new Win32Exception (error);
}
}
}
bool release = false;
try {
process_handle.DangerousAddRef (ref release);
void CheckExited () {
int error;
if (!SetPriorityClass (process_handle.DangerousGetHandle (), (int) value, out error)) {
if (HasExited)
throw new InvalidOperationException (String.Format ("Cannot process request because the process ({0}) has exited.", Id));
throw new Win32Exception (error);
}
} finally {
if (release)
process_handle.DangerousRelease ();
}
}
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
@ -514,7 +570,15 @@ namespace System.Diagnostics {
[MonitoringDescription ("The amount of processing time spent in the OS core for this process.")]
public TimeSpan PrivilegedProcessorTime {
get {
return new TimeSpan (Times (process_handle, 1));
bool release = false;
try {
process_handle.DangerousAddRef (ref release);
return new TimeSpan (Times (process_handle.DangerousGetHandle (), 1));
} finally {
if (release)
process_handle.DangerousRelease ();
}
}
}
@ -529,10 +593,20 @@ namespace System.Diagnostics {
get {
if(process_name==null) {
if (process_handle == IntPtr.Zero)
if (process_handle.IsInvalid)
throw new InvalidOperationException ("No process is associated with this object.");
process_name=ProcessName_internal(process_handle);
bool release = false;
try {
process_handle.DangerousAddRef (ref release);
process_name=ProcessName_internal(process_handle.DangerousGetHandle ());
} finally {
if (release)
process_handle.DangerousRelease ();
}
/* If process_name is _still_
* null, assume the process
* has exited
@ -682,7 +756,15 @@ namespace System.Diagnostics {
[MonitoringDescription ("The time this process started.")]
public DateTime StartTime {
get {
return(DateTime.FromFileTime(StartTime_internal(process_handle)));
bool release = false;
try {
process_handle.DangerousAddRef (ref release);
return(DateTime.FromFileTime(StartTime_internal(process_handle.DangerousGetHandle ())));
} finally {
if (release)
process_handle.DangerousRelease ();
}
}
}
@ -708,7 +790,15 @@ namespace System.Diagnostics {
[MonitoringDescription ("The total CPU time spent for this process.")]
public TimeSpan TotalProcessorTime {
get {
return new TimeSpan (Times (process_handle, 2));
bool release = false;
try {
process_handle.DangerousAddRef (ref release);
return new TimeSpan (Times (process_handle.DangerousGetHandle (), 2));
} finally {
if (release)
process_handle.DangerousRelease ();
}
}
}
@ -716,7 +806,15 @@ namespace System.Diagnostics {
[MonitoringDescription ("The CPU time spent for this process in user mode.")]
public TimeSpan UserProcessorTime {
get {
return new TimeSpan (Times (process_handle, 0));
bool release = false;
try {
process_handle.DangerousAddRef (ref release);
return new TimeSpan (Times (process_handle.DangerousGetHandle (), 0));
} finally {
if (release)
process_handle.DangerousRelease ();
}
}
}
@ -781,14 +879,21 @@ namespace System.Diagnostics {
/* int kill -> 1 KILL, 2 CloseMainWindow */
bool Close (int signo)
{
if (process_handle == IntPtr.Zero)
if (process_handle.IsInvalid)
throw new SystemException ("No process to kill.");
int exitcode = ExitCode_internal (process_handle);
if (exitcode != 259)
bool release = false;
try {
process_handle.DangerousAddRef (ref release);
if (ExitCode_internal (process_handle.DangerousGetHandle ()) != 259)
throw new InvalidOperationException ("The process already finished.");
return Kill_internal (process_handle, signo);
return Kill_internal (process_handle.DangerousGetHandle (), signo);
} finally {
if (release)
process_handle.DangerousRelease ();
}
}
public bool CloseMainWindow ()
@ -814,7 +919,7 @@ namespace System.Diagnostics {
if (proc == IntPtr.Zero)
throw new SystemException("Can't find current process");
return (new Process (proc, pid));
return (new Process (new SafeProcessHandle (proc), pid));
}
public static Process GetProcessById(int processId)
@ -824,7 +929,7 @@ namespace System.Diagnostics {
if (proc == IntPtr.Zero)
throw new ArgumentException ("Can't find process with ID " + processId.ToString ());
return (new Process (proc, processId));
return (new Process (new SafeProcessHandle (proc), processId));
}
[MonoTODO ("There is no support for retrieving process information from a remote machine")]
@ -957,7 +1062,7 @@ namespace System.Diagnostics {
throw new Win32Exception (-proc_info.pid);
}
process.process_handle = proc_info.process_handle;
process.process_handle = new SafeProcessHandle (proc_info.process_handle);
process.pid = proc_info.pid;
process.StartBackgroundWaitForExit ();
return(ret);
@ -1097,7 +1202,7 @@ namespace System.Diagnostics {
}
}
process.process_handle = proc_info.process_handle;
process.process_handle = new SafeProcessHandle (proc_info.process_handle);
process.pid = proc_info.pid;
if (startInfo.RedirectStandardInput) {
@ -1174,9 +1279,8 @@ namespace System.Diagnostics {
public bool Start ()
{
if (process_handle != IntPtr.Zero) {
Process_free_internal (process_handle);
process_handle = IntPtr.Zero;
if (!process_handle.IsInvalid) {
process_handle.Dispose ();
}
return Start_common(start_info, this);
}
@ -1188,7 +1292,7 @@ namespace System.Diagnostics {
Process process = new Process();
process.StartInfo = startInfo;
if (Start_common(startInfo, process) && process.process_handle != IntPtr.Zero)
if (Start_common(startInfo, process) && !process.process_handle.IsInvalid)
return process;
return null;
}
@ -1274,11 +1378,19 @@ namespace System.Diagnostics {
if (ms == int.MaxValue)
ms = -1;
if (process_handle == IntPtr.Zero)
if (process_handle.IsInvalid)
throw new InvalidOperationException ("No process is associated with this object.");
if (!WaitForExit_internal (process_handle, ms))
bool release = false;
try {
process_handle.DangerousAddRef (ref release);
if (!WaitForExit_internal (process_handle.DangerousGetHandle (), ms))
return false;
} finally {
if (release)
process_handle.DangerousRelease ();
}
#if MONO_FEATURE_PROCESS_START
if (async_output != null)
@ -1309,7 +1421,15 @@ namespace System.Diagnostics {
// The internal call is only implemented properly on Windows.
[MonoTODO]
public bool WaitForInputIdle(int milliseconds) {
return WaitForInputIdle_internal (process_handle, milliseconds);
bool release = false;
try {
process_handle.DangerousAddRef (ref release);
return WaitForInputIdle_internal (process_handle.DangerousGetHandle (), milliseconds);
} finally {
if (release)
process_handle.DangerousRelease ();
}
}
private static bool IsLocalMachine (string machineName)
@ -1344,7 +1464,7 @@ namespace System.Diagnostics {
[ComVisibleAttribute(false)]
public void BeginOutputReadLine ()
{
if (process_handle == IntPtr.Zero || output_stream == null || StartInfo.RedirectStandardOutput == false)
if (process_handle.IsInvalid || output_stream == null || StartInfo.RedirectStandardOutput == false)
throw new InvalidOperationException ("Standard output has not been redirected or process has not been started.");
if ((async_mode & AsyncModes.SyncOutput) != 0)
@ -1376,7 +1496,7 @@ namespace System.Diagnostics {
[ComVisibleAttribute(false)]
public void CancelOutputRead ()
{
if (process_handle == IntPtr.Zero || output_stream == null || StartInfo.RedirectStandardOutput == false)
if (process_handle.IsInvalid || output_stream == null || StartInfo.RedirectStandardOutput == false)
throw new InvalidOperationException ("Standard output has not been redirected or process has not been started.");
if ((async_mode & AsyncModes.SyncOutput) != 0)
@ -1393,7 +1513,7 @@ namespace System.Diagnostics {
[ComVisibleAttribute(false)]
public void BeginErrorReadLine ()
{
if (process_handle == IntPtr.Zero || error_stream == null || StartInfo.RedirectStandardError == false)
if (process_handle.IsInvalid || error_stream == null || StartInfo.RedirectStandardError == false)
throw new InvalidOperationException ("Standard error has not been redirected or process has not been started.");
if ((async_mode & AsyncModes.SyncError) != 0)
@ -1425,7 +1545,7 @@ namespace System.Diagnostics {
[ComVisibleAttribute(false)]
public void CancelErrorRead ()
{
if (process_handle == IntPtr.Zero || error_stream == null || StartInfo.RedirectStandardError == false)
if (process_handle.IsInvalid || error_stream == null || StartInfo.RedirectStandardError == false)
throw new InvalidOperationException ("Standard error has not been redirected or process has not been started.");
if ((async_mode & AsyncModes.SyncOutput) != 0)
@ -1468,7 +1588,7 @@ namespace System.Diagnostics {
[MonitoringDescription ("Raised when this process exits.")]
public event EventHandler Exited {
add {
if (process_handle != IntPtr.Zero && HasExited) {
if (!process_handle.IsInvalid && HasExited) {
value.BeginInvoke (null, null, null, null);
} else {
exited_event += value;
@ -1483,7 +1603,7 @@ namespace System.Diagnostics {
// Closes the system process handle
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void Process_free_internal(IntPtr handle);
private static extern void Process_free_internal(IntPtr handle);
int disposed;
@ -1519,9 +1639,8 @@ namespace System.Diagnostics {
// Release unmanaged resources
if (process_handle!=IntPtr.Zero) {
Process_free_internal (process_handle);
process_handle = IntPtr.Zero;
if (!process_handle.IsInvalid) {
process_handle.Dispose ();
}
base.Dispose (disposing);
@ -1572,20 +1691,31 @@ namespace System.Diagnostics {
void StartBackgroundWaitForExit ()
{
IntPtr handle = process_handle;
SafeProcessHandle handle = process_handle;
if (enable_raising_events == 0)
return;
if (exited_event == null)
return;
if (handle == IntPtr.Zero)
if (handle.IsInvalid)
return;
if (background_wait_for_exit_thread != null)
return;
Thread t = new Thread (_ => {
if (!WaitForExit_internal (handle, -1))
bool release = false;
try {
handle.DangerousAddRef (ref release);
if (!WaitForExit_internal (handle.DangerousGetHandle (), -1))
return;
} catch (ObjectDisposedException) {
if (release)
throw;
} finally {
if (release)
handle.DangerousRelease ();
}
if (EnableRaisingEvents)
OnExited ();
@ -1612,6 +1742,26 @@ namespace System.Diagnostics {
// closed, so no need to override dispose (bug #464628).
}
}
class SafeProcessHandle : SafeHandleZeroOrMinusOneIsInvalid
{
internal SafeProcessHandle ()
: base (false)
{
}
internal SafeProcessHandle (IntPtr handle)
: base (true)
{
SetHandle (handle);
}
override protected bool ReleaseHandle ()
{
Process_free_internal (handle);
return true;
}
}
}
}

View File

@ -1 +1 @@
8d48b675ae8cf9ed8a03cab67569bb1c49d9033d
0f1c977a71d57169dc91c54c8baa329f65d18b38

View File

@ -593,6 +593,7 @@ namespace System.Net
CheckRequestStarted ();
proxy = value;
servicePoint = null; // we may need a new one
GetServicePoint ();
}
}
@ -969,11 +970,17 @@ namespace System.Net
}
}
if (!requestSent) {
if (requestSent)
return;
try {
requestSent = true;
redirects = 0;
servicePoint = GetServicePoint ();
abortHandler = servicePoint.SendRequest (this, connectionGroup);
} catch (Exception ex) {
aread.SetCompleted (synch, ex);
aread.DoCallback ();
}
});

View File

@ -49,8 +49,6 @@ namespace System.Net
DateTime idleSince;
DateTime lastDnsResolve;
Version protocolVersion;
X509Certificate certificate;
X509Certificate clientCertificate;
IPHostEntry host;
bool usesProxy;
Dictionary<string,WebConnectionGroup> groups;
@ -92,14 +90,6 @@ namespace System.Net
set { endPointCallback = value; }
}
public X509Certificate Certificate {
get { return certificate; }
}
public X509Certificate ClientCertificate {
get { return clientCertificate; }
}
[MonoTODO]
public int ConnectionLeaseTimeout
{
@ -413,20 +403,55 @@ namespace System.Net
return false;
}
internal void SetServerCertificate (X509Certificate server)
//
// Copied from the referencesource
//
object m_ServerCertificateOrBytes;
object m_ClientCertificateOrBytes;
/// <devdoc>
/// <para>
/// Gets the certificate received for this <see cref='System.Net.ServicePoint'/>.
/// </para>
/// </devdoc>
public X509Certificate Certificate {
get {
object chkCert = m_ServerCertificateOrBytes;
if (chkCert != null && chkCert.GetType() == typeof(byte[]))
return (X509Certificate)(m_ServerCertificateOrBytes = new X509Certificate((byte[]) chkCert));
else
return chkCert as X509Certificate;
}
}
internal void UpdateServerCertificate(X509Certificate certificate)
{
var cloned = server != null ? new X509Certificate (server) : null;
var old = Interlocked.Exchange (ref certificate, cloned);
if (old != null)
old.Dispose ();
if (certificate != null)
m_ServerCertificateOrBytes = certificate.GetRawCertData();
else
m_ServerCertificateOrBytes = null;
}
internal void SetClientCertificate (X509Certificate clientCertificate)
/// <devdoc>
/// <para>
/// Gets the Client Certificate sent by us to the Server.
/// </para>
/// </devdoc>
public X509Certificate ClientCertificate {
get {
object chkCert = m_ClientCertificateOrBytes;
if (chkCert != null && chkCert.GetType() == typeof(byte[]))
return (X509Certificate)(m_ClientCertificateOrBytes = new X509Certificate((byte[]) chkCert));
else
return chkCert as X509Certificate;
}
}
internal void UpdateClientCertificate(X509Certificate certificate)
{
var cloned = clientCertificate != null ? new X509Certificate (clientCertificate) : null;
var old = Interlocked.Exchange (ref clientCertificate, cloned);
if (old != null)
old.Dispose ();
if (certificate != null)
m_ClientCertificateOrBytes = certificate.GetRawCertData();
else
m_ClientCertificateOrBytes = null;
}
internal bool CallEndPointDelegate (Socket sock, IPEndPoint remote)

View File

@ -114,7 +114,7 @@ namespace System.Net
// Static properties
private static ICertificatePolicy policy = new DefaultCertificatePolicy ();
private static ICertificatePolicy policy;
private static int defaultConnectionLimit = DefaultPersistentConnectionLimit;
private static int maxServicePointIdleTime = 100000; // 100 seconds
private static int maxServicePoints = 0;
@ -174,7 +174,11 @@ namespace System.Net
[Obsolete ("Use ServerCertificateValidationCallback instead", false)]
public static ICertificatePolicy CertificatePolicy {
get { return policy; }
get {
if (policy == null)
Interlocked.CompareExchange (ref policy, new DefaultCertificatePolicy (), null);
return policy;
}
set { policy = value; }
}
@ -328,7 +332,7 @@ namespace System.Net
usesProxy = true;
bool isSecure = address.Scheme == "https";
address = proxy.GetProxy (address);
if (address.Scheme != "http" && !isSecure)
if (address.Scheme != "http")
throw new NotSupportedException ("Proxy scheme not supported.");
if (isSecure && address.Scheme == "http")

View File

@ -419,6 +419,7 @@ namespace System.Net
status = tlsStream.ExceptionStatus;
else if (!request.Aborted)
status = WebExceptionStatus.ConnectFailure;
connect_exception = ex;
return false;
}
@ -992,9 +993,6 @@ namespace System.Net
internal bool EndWrite (HttpWebRequest request, bool throwOnError, IAsyncResult result)
{
if (request.FinishedReading)
return true;
Stream s = null;
lock (this) {
if (status == WebExceptionStatus.RequestCanceled)

View File

@ -397,6 +397,22 @@ namespace MonoTests.System.IO.Compression
compressing.Close ();
backing.Close ();
}
[Test]
public void Bug34916_Inflate ()
{
var base64String = @"H4sIAAAAAAAAA6yVu27bQBBF/4VtZGHeD3ZJmhTp5C5IIUiEIcCWDEUugiD/nmEQwYRNURFAsuFwd2exZ++d+farud89davT+um5aRsC1DuEO+R7lJayRV9m5gegFqBZNB83m5fjevOzadGWUPHjaXd62XYVEy3Z04wiMTKIX0dfV0G/6FO3Pu72D/+iL916W9GbOV/X58SaS6zEKKyoGUA1eNg/nLfF2jUEBBNMtT4Wzeq567Z9HkZkE1Osf93msN/+WO32m+7zsavsh30/BUU8fy+uUCC+QIHpPQW1RAXkEGWUmSnUy2iUYSMYOGpARYViiIHcqY5kExS8rg2vY8gLGEjeYsClBVE4ORQHz3kxsEF4iS01xzBIZkgYQcYQQ7C54LQaIrxWn5+4ioT1BiRQN8Fh6MrOPjOS9Eh3M8YRJJQMZioJkUODFA8RNJ9AYuYBNyGJW5D0oi3/EpZ3dWYk5X5PN81RJGJgDATMQ5X02nFS1imVlMGvu0XwBg5/K1hY1U8tecxcNDy1/FAnG+OAQSi9PliHRaNUiuoxQYFB6T8oyAUKEu9LJ6oipbr1spyZArhWX6qbi7EOUrs7SCAoDNVgzKagMlUz+q6DQ4N8/yM=";
byte[] byteArray = Convert.FromBase64String(base64String);
string unZipped = null;
using (var zippedMemoryStream = new MemoryStream (byteArray))
using (var gZipStream = new GZipStream (zippedMemoryStream, CompressionMode.Decompress))
using (var unzippedMemStream = new MemoryStream())
using (var unZippedStream = new StreamReader (gZipStream, Encoding.UTF8)) {
unZipped = unZippedStream.ReadToEnd ();
}
}
}
}

View File

@ -1 +1 @@
2f85b7b795ef33f0b58ccc3b51269444520bdab9
a0e19d4f2d15d6d856fcf37ff33c86c1173274d5

View File

@ -0,0 +1 @@
#include System.dll.sources

View File

@ -288,7 +288,8 @@ namespace System
var Istart = 0;
while (Istart < str.Length && !char.IsLetterOrDigit(str[Istart])) Istart++;
var Iend = str.Length - 1;
while (Iend > Istart && !char.IsLetterOrDigit(str[Iend])) Iend--;
while (Iend > Istart && !char.IsLetterOrDigit(str[Iend]) && str[Iend] != ')') // zone name can include parentheses like "Central Standard Time (Mexico)"
Iend--;
return str.Substring (Istart, Iend-Istart+1);
}

View File

@ -395,6 +395,96 @@ namespace MonoTests.System.Threading {
}
}
#if MONO_FEATURE_THREAD_SUSPEND_RESUME
[Test]
public void WaitOneWithTimeoutAndSpuriousWake ()
{
/* This is to test that WaitEvent.WaitOne is not going to wait largely
* more than its timeout. In this test, it shouldn't wait more than
* 1500 milliseconds, with its timeout being 1000ms */
using (ManualResetEvent mre = new ManualResetEvent (false))
using (ManualResetEvent ready = new ManualResetEvent (false)) {
var thread = new Thread (() => {
ready.Set ();
mre.WaitOne (1000);
});
thread.Start ();
ready.WaitOne ();
Thread.Sleep (10); // wait a bit so we enter mre.WaitOne
DateTime end = DateTime.Now.AddMilliseconds (500);
while (DateTime.Now < end) {
thread.Suspend ();
thread.Resume ();
}
Assert.IsTrue (thread.Join (1000), "#1");
}
}
[Test]
public void WaitAnyWithTimeoutAndSpuriousWake ()
{
/* This is to test that WaitEvent.WaitAny is not going to wait largely
* more than its timeout. In this test, it shouldn't wait more than
* 1500 milliseconds, with its timeout being 1000ms */
using (ManualResetEvent mre1 = new ManualResetEvent (false))
using (ManualResetEvent mre2 = new ManualResetEvent (false))
using (ManualResetEvent ready = new ManualResetEvent (false)) {
var thread = new Thread (() => {
ready.Set ();
WaitHandle.WaitAny (new [] { mre1, mre2 }, 1000);
});
thread.Start ();
ready.WaitOne ();
Thread.Sleep (10); // wait a bit so we enter WaitHandle.WaitAny ({mre1, mre2})
DateTime end = DateTime.Now.AddMilliseconds (500);
while (DateTime.Now < end) {
thread.Suspend ();
thread.Resume ();
}
Assert.IsTrue (thread.Join (1000), "#1");
}
}
[Test]
public void WaitAllWithTimeoutAndSpuriousWake ()
{
/* This is to test that WaitEvent.WaitAll is not going to wait largely
* more than its timeout. In this test, it shouldn't wait more than
* 1500 milliseconds, with its timeout being 1000ms */
using (ManualResetEvent mre1 = new ManualResetEvent (false))
using (ManualResetEvent mre2 = new ManualResetEvent (false))
using (ManualResetEvent ready = new ManualResetEvent (false)) {
var thread = new Thread (() => {
ready.Set ();
WaitHandle.WaitAll (new [] { mre1, mre2 }, 1000);
});
thread.Start ();
ready.WaitOne ();
Thread.Sleep (10); // wait a bit so we enter WaitHandle.WaitAll ({mre1, mre2})
DateTime end = DateTime.Now.AddMilliseconds (500);
while (DateTime.Now < end) {
thread.Suspend ();
thread.Resume ();
}
Assert.IsTrue (thread.Join (1000), "#1");
}
}
#endif // MONO_FEATURE_THREAD_SUSPEND_RESUME
}
}

View File

@ -1 +1 @@
8f5979d27ed2a52fccb1bc587845fb652a05412c
362e108c1374bb987f401f2b4d420b050a031231

View File

@ -1 +1 @@
842cbee0abeca01699b2af178bde507d4d52b277
c64b6fef099910e33f49c5132d6568abfbdf62b3

View File

@ -1 +1 @@
0a1c99b3277a99080d40a64a7da507e2d61460f0
24979c09819a656e19fc58fcf19e9b5a16584075

View File

@ -1 +1 @@
bd0d7c1a8100803b2ef6da3853c7045cc83c4824
bd4b36083e46dd607da7e0ec9922f22c312cf270

View File

@ -1 +1 @@
107c45faacbffc3876e310e13f5528c765944ba4
2caa7c6153cffdaf2f9392820e8c2468e5b287af

View File

@ -64,7 +64,7 @@ namespace MonoTests.Helpers
tcpListener = new TcpListener (ep);
tcpListener.Start ();
listenTask = Task.Run (Listen);
listenTask = Task.Run ((Action) Listen);
}
public void Dispose ()

11
mcs/errors/cs8082-2.cs Normal file
View File

@ -0,0 +1,11 @@
// CS8082: An argument to nameof operator cannot include sub-expression
// Line: 9
class C
{
void Foo ()
{
dynamic o = null;
var s = nameof (o.ToString ().Equals);
}
}

10
mcs/errors/cs8082-3.cs Normal file
View File

@ -0,0 +1,10 @@
// CS8082: An argument to nameof operator cannot include sub-expression
// Line: 8
class C
{
void Foo ()
{
var v = nameof (this?.Equals);
}
}

10
mcs/errors/cs8082-4.cs Normal file
View File

@ -0,0 +1,10 @@
// CS8082: An argument to nameof operator cannot include sub-expression
// Line: 8
class C
{
void Foo ()
{
var s = nameof (1.ToString);
}
}

View File

@ -90,6 +90,11 @@ namespace Mono.CSharp
if (!stmt.Resolve (bc))
return null;
if (rc.HasSet (ResolveContext.Options.FinallyScope) && rc.CurrentAnonymousMethod != null) {
var ats = (AsyncTaskStorey)rc.CurrentAnonymousMethod.Storey;
ats.HasAwaitInsideFinally = true;
}
type = stmt.ResultType;
eclass = ExprClass.Variable;
return this;
@ -344,7 +349,11 @@ namespace Mono.CSharp
var errors_printer = new SessionReportPrinter ();
var old = bc.Report.SetPrinter (errors_printer);
ama = new Invocation (ama, args).Resolve (bc);
//
// The expression await t is classified the same way as the expression (t).GetAwaiter().GetResult().
//
ama = new Invocation (new ParenthesizedExpression (ama, Location.Null), args).Resolve (bc);
bc.Report.SetPrinter (old);
if (errors_printer.ErrorsCount > 0 || !MemberAccess.IsValidDotExpression (ama.Type)) {
@ -536,6 +545,8 @@ namespace Mono.CSharp
#region Properties
public bool HasAwaitInsideFinally { get; set; }
public Expression HoistedReturnValue { get; set; }
public TypeSpec ReturnType {
@ -689,6 +700,18 @@ namespace Mono.CSharp
builder = AddCompilerGeneratedField ("$builder", new TypeExpression (bt, Location));
Field rfield;
if (has_task_return_type && HasAwaitInsideFinally) {
//
// Special case async block with return value from finally clause. In such case
// we rewrite all return expresison stores to stfld to $return. Instead of treating
// returns outside of finally and inside of finally differently.
//
rfield = AddCompilerGeneratedField ("$return", new TypeExpression (bt.TypeArguments [0], Location));
} else {
rfield = null;
}
var set_state_machine = new Method (this, new TypeExpression (Compiler.BuiltinTypes.Void, Location),
Modifiers.COMPILER_GENERATED | Modifiers.DEBUGGER_HIDDEN | Modifiers.PUBLIC,
new MemberName ("SetStateMachine"),
@ -726,8 +749,14 @@ namespace Mono.CSharp
set_state_machine.Block.AddStatement (new StatementExpression (new Invocation (mg, args)));
if (has_task_return_type) {
if (rfield != null) {
HoistedReturnValue = new FieldExpr (rfield, Location) {
InstanceExpression = new CompilerGeneratedThis (CurrentType, Location.Null)
};
} else {
HoistedReturnValue = TemporaryVariableReference.Create (bt.TypeArguments [0], StateMachineMethod.Block, Location);
}
}
return true;
}

View File

@ -2179,8 +2179,11 @@ namespace Mono.CSharp {
var ma = expr as MemberAccess;
if (ma != null) {
var lexpr = ma.LeftExpression;
Expression res;
var res = ma.LookupNameExpression (rc, MemberLookupRestrictions.IgnoreAmbiguity);
using (rc.Set (ResolveContext.Options.NameOfScope)) {
res = ma.LookupNameExpression (rc, MemberLookupRestrictions.IgnoreAmbiguity);
}
if (res == null) {
return false;
@ -2194,11 +2197,6 @@ namespace Mono.CSharp {
return false;
}
if (!IsLeftExpressionValid (lexpr)) {
rc.Report.Error (8082, lexpr.Location, "An argument to nameof operator cannot include sub-expression");
return false;
}
var mg = res as MethodGroupExpr;
if (mg != null) {
var emg = res as ExtensionMethodGroupExpr;
@ -2215,6 +2213,14 @@ namespace Mono.CSharp {
}
}
//
// LAMESPEC: Why is conditional access not allowed?
//
if (!IsLeftResolvedExpressionValid (ma.LeftExpression) || ma.HasConditionalAccess ()) {
rc.Report.Error (8082, lexpr.Location, "An argument to nameof operator cannot include sub-expression");
return false;
}
Value = ma.Name;
return true;
}
@ -2223,26 +2229,25 @@ namespace Mono.CSharp {
return false;
}
static bool IsLeftExpressionValid (Expression expr)
static bool IsLeftResolvedExpressionValid (Expression expr)
{
if (expr is SimpleName)
return true;
if (expr is This)
return true;
if (expr is NamespaceExpression)
return true;
if (expr is TypeExpr)
return true;
var ma = expr as MemberAccess;
if (ma != null) {
// TODO: Will conditional access be allowed?
return IsLeftExpressionValid (ma.LeftExpression);
var fe = expr as FieldExpr;
if (fe != null) {
return fe.InstanceExpression == null || IsLeftResolvedExpressionValid (fe.InstanceExpression);
}
var pe = expr as PropertyExpr;
if (pe != null)
return pe.InstanceExpression == null || IsLeftResolvedExpressionValid (pe.InstanceExpression);
var dmb = expr as DynamicMemberBinder;
if (dmb != null) {
return IsLeftResolvedExpressionValid (dmb.Arguments [0].Expr);
}
if (expr is ConstantExpr || expr is TypeExpr || expr is NamespaceExpression || expr is This)
return true;
return false;
}

View File

@ -191,6 +191,8 @@ namespace Mono.CSharp
DontSetConditionalAccessReceiver = 1 << 16,
NameOfScope = 1 << 17,
///
/// Indicates the current context is in probing mode, no errors are reported.
///

View File

@ -4058,6 +4058,9 @@ namespace Mono.CSharp
--braces;
break;
case '\\':
if (parsing_string_interpolation_quoted != null && parsing_string_interpolation_quoted.Peek ())
break;
++col;
int surrogate;
ch = escape (ch, out surrogate);

View File

@ -1 +1 @@
52da19a1b970748d49991d1a2b47a7bbef11a061
a581906d3e9b82d7ffd04ab74c4c1f8275e7efa5

View File

@ -1 +1 @@
c5139d57f673c5d02f003618a9d64ccc09dcc2a1
bfba44fbb8c656079254fc346737ea8a4af5fd3e

View File

@ -897,6 +897,18 @@ namespace Mono.CSharp.Nullable
ec.MarkLabel (is_null_label);
LiftedNull.Create (type, loc).Emit (ec);
} else if (Left.IsNull && UnwrapRight != null) {
UnwrapRight.Emit (ec);
ec.Emit (or ? OpCodes.Brtrue_S : OpCodes.Brfalse_S, load_right);
LiftedNull.Create (type, loc).Emit (ec);
ec.Emit (OpCodes.Br_S, end_label);
ec.MarkLabel (load_right);
UnwrapRight.Load (ec);
} else {
Right.Emit (ec);
ec.Emit (or ? OpCodes.Brfalse_S : OpCodes.Brtrue_S, load_left);

View File

@ -1210,6 +1210,16 @@ namespace Mono.CSharp {
settings.RuntimeMetadataVersion = value;
return ParseResult.Success;
// csc options that we don't support
case "/utf8output":
case "/subsystemversion":
case "/highentropyva":
case "/highentropyva+":
case "/highentropyva-":
case "/win32manifest":
case "/nowin32manifest":
return ParseResult.Success;
default:
return ParseResult.UnknownOption;
}

View File

@ -1 +1 @@
e5c8bb4316c6b5af4ce075f1b939559bf7efd40f
3fbb360debcdacf3146092c1a7adddf7f20f3fde

View File

@ -99,6 +99,35 @@ class C
if ((null | b4) != true)
return 103;
bool? x_n = null;
bool? x_f = false;
bool? x_t = true;
bool? res;
res = null & x_n;
if (res.HasValue)
return 201;
res = null & x_t;
if (res.HasValue)
return 202;
res = null & x_f;
if (res.Value != false)
return 203;
res = null | x_n;
if (res.HasValue)
return 204;
res = null | x_t;
if (res.Value != true)
return 205;
res = null | x_f;
if (res.HasValue)
return 206;
return 0;
}

View File

@ -0,0 +1,30 @@
using System;
using System.Threading.Tasks;
class X
{
public static int Main ()
{
if (new X ().Test (false).Result != true)
return 1;
if (new X ().Test (true).Result != true)
return 2;
return 0;
}
public async Task<bool> Test(bool TrueOrFalse)
{
if (TrueOrFalse)
return true;
try {
return true;
}
finally
{
await Task.Yield ();
}
}
}

View File

@ -0,0 +1,34 @@
using System;
using System.Threading.Tasks;
class MainClass
{
public static int Main ()
{
var t = GetSomeStrings (null);
try {
var s = t.Result;
return 1;
} catch (AggregateException e) {
if (e.InnerException is NullReferenceException)
return 0;
return 2;
}
}
public static async Task<string> GetSomeStrings (AsyncStringFactory myFactory)
{
var res = await myFactory?.GetSomeStringAsync ();
return res;
}
}
public class AsyncStringFactory
{
public async Task<string> GetSomeStringAsync ()
{
await Task.Yield();
return "foo";
}
}

View File

@ -0,0 +1,35 @@
using System;
using System.Threading.Tasks;
struct S
{
public int value;
public string str;
}
public class Program
{
async Task<S> Foo ()
{
return new S {
value = 1,
str = await DoAsync ()
};
}
static async Task<string> DoAsync ()
{
await Task.Yield ();
return "asdafs";
}
static int Main ()
{
var res = new Program ().Foo ().Result;
if (res.value != 1)
return 1;
return 0;
}
}

View File

@ -0,0 +1,16 @@
using System;
class EscapedQuotedInterpolatedFormatSpecifier
{
public static int Main ()
{
string ss = "ss";
var t = $@"\4{ss:\u007B}\5";
Console.WriteLine (t);
if (t != @"\4ss\5")
return 1;
return 0;
}
}

View File

@ -0,0 +1,66 @@
// Compiler options: -warnaserror
using System;
public class Person
{
public Car MyCar { get; set; }
}
public class Car
{
public int Year { get; set; }
}
enum EE
{
K
}
public class MainClass
{
class Nested
{
}
public static Person MyPerson1 { get; } = new Person();
public static Person MyPerson2 = new Person();
public const Person MyPerson3 = null;
public static event Action Act = null;
public static dynamic BBB = null;
public static int Main ()
{
string name;
name = nameof (MyPerson1.MyCar.Year);
if (name != "Year")
return 1;
name = nameof (MyPerson2.MyCar.Year);
if (name != "Year")
return 2;
name = nameof (MyPerson3.MyCar.Year);
if (name != "Year")
return 3;
name = nameof (Act.Method.MemberType);
if (name != "MemberType")
return 4;
name = nameof (BBB.A.B.C);
if (name != "C")
return 5;
name = nameof (EE.K.ToString);
if (name != "ToString")
return 6;
name = nameof (int.ToString);
if (name != "ToString")
return 7;
return 0;
}
}

View File

@ -1 +1 @@
dcd5f610003bf7b72bb83316c5aeefb95f9e64ce
55a55a8ce00b5f19846f2a4e0df099c17d0799cd

View File

@ -345,10 +345,12 @@ void mono_register_config_for_assembly (const char* assembly_name, cons
// The non-parallel part
byte [] buffer = new byte [8192];
// everything other than a-zA-Z0-9_ needs to be escaped in asm symbols.
var symbolEscapeRE = new System.Text.RegularExpressions.Regex ("[^\\w_]");
foreach (var url in files) {
string fname = LocateFile (new Uri (url).LocalPath);
string aname = Path.GetFileName (fname);
string encoded = aname.Replace ("-", "_").Replace (".", "_");
string encoded = symbolEscapeRE.Replace (aname, "_");
if (prog == null)
prog = aname;
@ -550,7 +552,7 @@ void mono_register_config_for_assembly (const char* assembly_name, cons
smonolib = "`pkg-config --variable=libdir mono-2`/libmono-2.0.a ";
else
smonolib = "-Wl,-Bstatic -lmono-2.0 -Wl,-Bdynamic ";
cmd = String.Format("{4} -o {2} -Wall `pkg-config --cflags mono-2` {0} {3} " +
cmd = String.Format("{4} -o '{2}' -Wall `pkg-config --cflags mono-2` {0} {3} " +
"`pkg-config --libs-only-L mono-2` " + smonolib +
"`pkg-config --libs-only-l mono-2 | sed -e \"s/\\-lmono-2.0 //\"` {1}",
temp_c, temp_o, output, zlib, cc);
@ -558,7 +560,7 @@ void mono_register_config_for_assembly (const char* assembly_name, cons
else
{
cmd = String.Format("{4} " + debugging + " -o {2} -Wall {0} `pkg-config --cflags --libs mono-2` {3} {1}",
cmd = String.Format("{4} " + debugging + " -o '{2}' -Wall {0} `pkg-config --cflags --libs mono-2` {3} {1}",
temp_c, temp_o, output, zlib, cc);
}
Execute (cmd);

View File

@ -83,6 +83,11 @@ install-web-targets:
$(INSTALL_DATA) targets/Microsoft.WebApplication.targets $(DESTDIR)$(VS_TARGETS_DIR)/v10.0/WebApplications
$(MKINSTALLDIRS) $(DESTDIR)$(VS_TARGETS_DIR)/v11.0/WebApplications
$(INSTALL_DATA) targets/Microsoft.WebApplication.targets $(DESTDIR)$(VS_TARGETS_DIR)/v11.0/WebApplications
$(MKINSTALLDIRS) $(DESTDIR)$(VS_TARGETS_DIR)/v12.0/WebApplications
$(INSTALL_DATA) targets/Microsoft.WebApplication.targets $(DESTDIR)$(VS_TARGETS_DIR)/v12.0/WebApplications
$(MKINSTALLDIRS) $(DESTDIR)$(VS_TARGETS_DIR)/v14.0/WebApplications
$(INSTALL_DATA) targets/Microsoft.WebApplication.targets $(DESTDIR)$(VS_TARGETS_DIR)/v14.0/WebApplications
EXTRA_DISTFILES = \
data/xbuild.rsp \

View File

@ -30,7 +30,6 @@
<AssemblyName Condition="'$(AssemblyName)' == ''">$(MSBuildProjectName)</AssemblyName>
<OutputPath Condition="'$(OutputPath)' != '' and !HasTrailingSlash('$(OutputPath)')">$(OutputPath)\</OutputPath>
<OutputPath Condition=" '$(Platform)'=='' and '$(Configuration)'=='' and '$(OutputPath)'=='' ">bin\Debug\</OutputPath>
<WarningLevel Condition="'$(WarningLevel)' == ''" >2</WarningLevel>
<TargetFrameworkIdentifier Condition="'$(TargetFrameworkIdentifier)' == ''">.NETFramework</TargetFrameworkIdentifier>
<TargetFrameworkVersion Condition="'$(TargetFrameworkVersion)' == ''">v4.0</TargetFrameworkVersion>

View File

@ -30,7 +30,6 @@
<AssemblyName Condition="'$(AssemblyName)' == ''">$(MSBuildProjectName)</AssemblyName>
<OutputPath Condition="'$(OutputPath)' != '' and !HasTrailingSlash('$(OutputPath)')">$(OutputPath)\</OutputPath>
<OutputPath Condition=" '$(Platform)'=='' and '$(Configuration)'=='' and '$(OutputPath)'=='' ">bin\Debug\</OutputPath>
<WarningLevel Condition="'$(WarningLevel)' == ''" >2</WarningLevel>
<TargetFrameworkIdentifier Condition="'$(TargetFrameworkIdentifier)' == ''">.NETFramework</TargetFrameworkIdentifier>
<TargetFrameworkVersion Condition="'$(TargetFrameworkVersion)' == ''">v4.0</TargetFrameworkVersion>

View File

@ -18,7 +18,6 @@
<AssemblyName Condition="'$(AssemblyName)' == ''">$(MSBuildProjectName)</AssemblyName>
<OutputPath Condition="'$(OutputPath)' != '' and !HasTrailingSlash('$(OutputPath)')">$(OutputPath)\</OutputPath>
<OutputPath Condition=" '$(Platform)'=='' and '$(Configuration)'=='' and '$(OutputPath)'=='' ">bin\Debug\</OutputPath>
<WarningLevel Condition="'$(WarningLevel)' == ''" >2</WarningLevel>
<TargetFrameworkVersion Condition="'$(TargetFrameworkVersion)' == ''">v2.0</TargetFrameworkVersion>
</PropertyGroup>

View File

@ -18,7 +18,6 @@
<AssemblyName Condition="'$(AssemblyName)' == ''">$(MSBuildProjectName)</AssemblyName>
<OutputPath Condition="'$(OutputPath)' != '' and !HasTrailingSlash('$(OutputPath)')">$(OutputPath)\</OutputPath>
<OutputPath Condition=" '$(Platform)'=='' and '$(Configuration)'=='' and '$(OutputPath)'=='' ">bin\Debug\</OutputPath>
<WarningLevel Condition="'$(WarningLevel)' == ''" >2</WarningLevel>
<TargetFrameworkVersion Condition="'$(TargetFrameworkVersion)' == ''">v2.0</TargetFrameworkVersion>
</PropertyGroup>

View File

@ -30,7 +30,6 @@
<AssemblyName Condition="'$(AssemblyName)' == ''">$(MSBuildProjectName)</AssemblyName>
<OutputPath Condition="'$(OutputPath)' != '' and !HasTrailingSlash('$(OutputPath)')">$(OutputPath)\</OutputPath>
<OutputPath Condition=" '$(Platform)'=='' and '$(Configuration)'=='' and '$(OutputPath)'=='' ">bin\Debug\</OutputPath>
<WarningLevel Condition="'$(WarningLevel)' == ''" >2</WarningLevel>
<TargetFrameworkIdentifier Condition="'$(TargetFrameworkIdentifier)' == ''">.NETFramework</TargetFrameworkIdentifier>
<TargetFrameworkVersion Condition="'$(TargetFrameworkVersion)' == ''">v4.0</TargetFrameworkVersion>

View File

@ -17,6 +17,7 @@
#include <mono/io-layer/wapi-private.h>
#include <mono/io-layer/io-trace.h>
#include <mono/utils/mono-logger-internals.h>
#include <mono/utils/mono-time.h>
static gboolean own_if_signalled(gpointer handle)
{
@ -88,6 +89,7 @@ guint32 WaitForSingleObjectEx(gpointer handle, guint32 timeout,
int thr_ret;
gboolean apc_pending = FALSE;
gpointer current_thread = wapi_get_current_thread_handle ();
gint64 now, end;
if (current_thread == NULL) {
SetLastError (ERROR_INVALID_HANDLE);
@ -157,6 +159,9 @@ guint32 WaitForSingleObjectEx(gpointer handle, guint32 timeout,
goto done;
}
if (timeout != INFINITE)
end = mono_100ns_ticks () + timeout * 1000 * 10;
do {
/* Check before waiting on the condition, just in case
*/
@ -170,7 +175,17 @@ guint32 WaitForSingleObjectEx(gpointer handle, guint32 timeout,
goto done;
}
waited = _wapi_handle_timedwait_signal_handle (handle, timeout, alertable, FALSE, &apc_pending);
if (timeout == INFINITE) {
waited = _wapi_handle_timedwait_signal_handle (handle, INFINITE, alertable, FALSE, &apc_pending);
} else {
now = mono_100ns_ticks ();
if (end < now) {
ret = WAIT_TIMEOUT;
goto done;
}
waited = _wapi_handle_timedwait_signal_handle (handle, (end - now) / 10 / 1000, alertable, FALSE, &apc_pending);
}
if(waited==0 && !apc_pending) {
/* Condition was signalled, so hopefully
@ -253,6 +268,7 @@ guint32 SignalObjectAndWait(gpointer signal_handle, gpointer wait,
int thr_ret;
gboolean apc_pending = FALSE;
gpointer current_thread = wapi_get_current_thread_handle ();
gint64 now, end;
if (current_thread == NULL) {
SetLastError (ERROR_INVALID_HANDLE);
@ -327,6 +343,9 @@ guint32 SignalObjectAndWait(gpointer signal_handle, gpointer wait,
goto done;
}
if (timeout != INFINITE)
end = mono_100ns_ticks () + timeout * 1000 * 10;
do {
/* Check before waiting on the condition, just in case
*/
@ -339,7 +358,17 @@ guint32 SignalObjectAndWait(gpointer signal_handle, gpointer wait,
goto done;
}
waited = _wapi_handle_timedwait_signal_handle (wait, timeout, alertable, FALSE, &apc_pending);
if (timeout == INFINITE) {
waited = _wapi_handle_timedwait_signal_handle (wait, INFINITE, alertable, FALSE, &apc_pending);
} else {
now = mono_100ns_ticks ();
if (end < now) {
ret = WAIT_TIMEOUT;
goto done;
}
waited = _wapi_handle_timedwait_signal_handle (wait, (end - now) / 10 / 1000, alertable, FALSE, &apc_pending);
}
if (waited==0 && !apc_pending) {
/* Condition was signalled, so hopefully
@ -445,6 +474,7 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
gboolean poll;
gpointer sorted_handles [MAXIMUM_WAIT_OBJECTS];
gboolean apc_pending = FALSE;
gint64 now, end;
if (current_thread == NULL) {
SetLastError (ERROR_INVALID_HANDLE);
@ -528,6 +558,10 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
if (timeout == 0) {
return WAIT_TIMEOUT;
}
if (timeout != INFINITE)
end = mono_100ns_ticks () + timeout * 1000 * 10;
/* Have to wait for some or all handles to become signalled
*/
@ -571,7 +605,16 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
if (!done) {
/* Enter the wait */
ret = _wapi_handle_timedwait_signal (timeout, poll, &apc_pending);
if (timeout == INFINITE) {
ret = _wapi_handle_timedwait_signal (INFINITE, poll, &apc_pending);
} else {
now = mono_100ns_ticks ();
if (end < now) {
ret = WAIT_TIMEOUT;
} else {
ret = _wapi_handle_timedwait_signal ((end - now) / 10 / 1000, poll, &apc_pending);
}
}
} else {
/* No need to wait */
ret = 0;

View File

@ -1046,6 +1046,7 @@ do_mono_image_load (MonoImage *image, MonoImageOpenStatus *status,
}
}
if (!image->loader) {
if (status)
*status = MONO_IMAGE_IMAGE_INVALID;
goto invalid_image;
}

View File

@ -601,7 +601,7 @@ jit_info_table_add (MonoDomain *domain, MonoJitInfoTable *volatile *table_ptr, M
*table_ptr = new_table;
mono_memory_barrier ();
domain->num_jit_info_tables++;
mono_thread_hazardous_free_or_queue (table, (MonoHazardousFreeFunc)mono_jit_info_table_free, TRUE, FALSE);
mono_thread_hazardous_free_or_queue (table, (MonoHazardousFreeFunc)mono_jit_info_table_free, HAZARD_FREE_MAY_LOCK, HAZARD_FREE_SAFE_CTX);
table = new_table;
goto restart;
@ -677,7 +677,7 @@ mono_jit_info_free_or_queue (MonoDomain *domain, MonoJitInfo *ji)
if (domain->num_jit_info_tables <= 1) {
/* Can it actually happen that we only have one table
but ji is still hazardous? */
mono_thread_hazardous_free_or_queue (ji, g_free, TRUE, FALSE);
mono_thread_hazardous_free_or_queue (ji, g_free, HAZARD_FREE_MAY_LOCK, HAZARD_FREE_SAFE_CTX);
} else {
domain->jit_info_free_queue = g_slist_prepend (domain->jit_info_free_queue, ji);
}

View File

@ -57,11 +57,10 @@ ves_icall_System_Diagnostics_Process_GetPid_internal (void)
return mono_process_current_pid ();
}
void ves_icall_System_Diagnostics_Process_Process_free_internal (MonoObject *this_obj,
HANDLE process)
void ves_icall_System_Diagnostics_Process_Process_free_internal (HANDLE process)
{
#ifdef THREAD_DEBUG
g_message ("%s: Closing process %p, handle %p", __func__, this_obj, process);
g_message ("%s: Closing process handle %p", __func__, process);
#endif
#if defined(TARGET_WIN32) || defined(HOST_WIN32)

View File

@ -60,7 +60,7 @@ G_BEGIN_DECLS
HANDLE ves_icall_System_Diagnostics_Process_GetProcess_internal (guint32 pid);
MonoArray *ves_icall_System_Diagnostics_Process_GetProcesses_internal (void);
guint32 ves_icall_System_Diagnostics_Process_GetPid_internal (void);
void ves_icall_System_Diagnostics_Process_Process_free_internal (MonoObject *this_obj, HANDLE process);
void ves_icall_System_Diagnostics_Process_Process_free_internal (HANDLE process);
MonoArray *ves_icall_System_Diagnostics_Process_GetModules_internal (MonoObject *this_obj, HANDLE process);
void ves_icall_System_Diagnostics_FileVersionInfo_GetVersionInfo_internal (MonoObject *this_obj, MonoString *filename);
MonoBoolean ves_icall_System_Diagnostics_Process_ShellExecuteEx_internal (MonoProcessStartInfo *proc_start_info, MonoProcInfo *process_handle);

View File

@ -2338,8 +2338,6 @@ mono_gc_scan_object (void *obj, void *gc_data)
void
sgen_client_scan_thread_data (void *start_nursery, void *end_nursery, gboolean precise, ScanCopyContext ctx)
{
SgenThreadInfo *info;
scan_area_arg_start = start_nursery;
scan_area_arg_end = end_nursery;
@ -2393,7 +2391,7 @@ sgen_client_scan_thread_data (void *start_nursery, void *end_nursery, gboolean p
}
}
}
} END_FOREACH_THREAD
} FOREACH_THREAD_END
}
/*

View File

@ -112,12 +112,11 @@ sgen_thread_handshake (BOOL suspend)
{
SgenThreadInfo *cur_thread = mono_thread_info_current ();
kern_return_t ret;
SgenThreadInfo *info;
int count = 0;
cur_thread->client_info.suspend_done = TRUE;
FOREACH_THREAD_SAFE (info) {
FOREACH_THREAD (info) {
if (info == cur_thread || sgen_thread_pool_is_thread_pool_thread (mono_thread_info_get_tid (info)))
continue;
@ -134,7 +133,7 @@ sgen_thread_handshake (BOOL suspend)
continue;
}
count ++;
} END_FOREACH_THREAD_SAFE
} FOREACH_THREAD_END
return count;
}

View File

@ -197,14 +197,13 @@ int
sgen_thread_handshake (BOOL suspend)
{
int count, result;
SgenThreadInfo *info;
int signum = suspend ? suspend_signal_num : restart_signal_num;
MonoNativeThreadId me = mono_native_thread_id_get ();
count = 0;
mono_thread_info_current ()->client_info.suspend_done = TRUE;
FOREACH_THREAD_SAFE (info) {
FOREACH_THREAD (info) {
if (mono_native_thread_id_equals (mono_thread_info_get_tid (info), me)) {
continue;
}
@ -219,7 +218,7 @@ sgen_thread_handshake (BOOL suspend)
} else {
info->client_info.skip = 1;
}
} END_FOREACH_THREAD_SAFE
} FOREACH_THREAD_END
sgen_wait_for_suspend_ack (count);

View File

@ -123,12 +123,11 @@ sgen_wait_for_suspend_ack (int count)
int
sgen_thread_handshake (BOOL suspend)
{
SgenThreadInfo *info;
SgenThreadInfo *current = mono_thread_info_current ();
int count = 0;
current->client_info.suspend_done = TRUE;
FOREACH_THREAD_SAFE (info) {
FOREACH_THREAD (info) {
if (info == current)
continue;
info->client_info.suspend_done = FALSE;
@ -142,7 +141,7 @@ sgen_thread_handshake (BOOL suspend)
continue;
}
++count;
} END_FOREACH_THREAD_SAFE
} FOREACH_THREAD_END
return count;
}

View File

@ -113,7 +113,6 @@ is_ip_in_managed_allocator (MonoDomain *domain, gpointer ip)
static int
restart_threads_until_none_in_managed_allocator (void)
{
SgenThreadInfo *info;
int num_threads_died = 0;
int sleep_duration = -1;
@ -121,7 +120,7 @@ restart_threads_until_none_in_managed_allocator (void)
int restart_count = 0, restarted_count = 0;
/* restart all threads that stopped in the
allocator */
FOREACH_THREAD_SAFE (info) {
FOREACH_THREAD (info) {
gboolean result;
if (info->client_info.skip || info->client_info.gc_disabled || info->client_info.suspend_done)
continue;
@ -146,7 +145,7 @@ restart_threads_until_none_in_managed_allocator (void)
info->client_info.stopped_domain = NULL;
info->client_info.suspend_done = TRUE;
}
} END_FOREACH_THREAD_SAFE
} FOREACH_THREAD_END
/* if no threads were restarted, we're done */
if (restart_count == 0)
break;
@ -174,7 +173,7 @@ restart_threads_until_none_in_managed_allocator (void)
} else {
info->client_info.skip = 1;
}
} END_FOREACH_THREAD
} FOREACH_THREAD_END
/* some threads might have died */
num_threads_died += restart_count - restarted_count;
/* wait for the threads to signal their suspension
@ -251,7 +250,6 @@ sgen_client_stop_world (int generation)
void
sgen_client_restart_world (int generation, GGTimingInfo *timing)
{
SgenThreadInfo *info;
TV_DECLARE (end_sw);
TV_DECLARE (start_handshake);
TV_DECLARE (end_bridge);
@ -269,7 +267,7 @@ sgen_client_restart_world (int generation, GGTimingInfo *timing)
#else
memset (&info->client_info.regs, 0, sizeof (info->client_info.regs));
#endif
} END_FOREACH_THREAD
} FOREACH_THREAD_END
TV_GETTIME (start_handshake);
@ -387,13 +385,12 @@ static void
sgen_unified_suspend_stop_world (void)
{
int restart_counter;
SgenThreadInfo *info;
int sleep_duration = -1;
mono_threads_begin_global_suspend ();
THREADS_STW_DEBUG ("[GC-STW-BEGIN] *** BEGIN SUSPEND *** \n");
FOREACH_THREAD_SAFE (info) {
FOREACH_THREAD (info) {
info->client_info.skip = FALSE;
info->client_info.suspend_done = FALSE;
if (sgen_is_thread_in_current_stw (info)) {
@ -402,14 +399,14 @@ sgen_unified_suspend_stop_world (void)
} else {
THREADS_STW_DEBUG ("[GC-STW-BEGIN-SUSPEND] IGNORE thread %p skip %d\n", mono_thread_info_get_tid (info), info->client_info.skip);
}
} END_FOREACH_THREAD_SAFE
} FOREACH_THREAD_END
mono_thread_info_current ()->client_info.suspend_done = TRUE;
mono_threads_wait_pending_operations ();
for (;;) {
restart_counter = 0;
FOREACH_THREAD_SAFE (info) {
FOREACH_THREAD (info) {
if (info->client_info.suspend_done || !sgen_is_thread_in_current_stw (info)) {
THREADS_STW_DEBUG ("[GC-STW-RESTART] IGNORE thread %p not been processed done %d current %d\n", mono_thread_info_get_tid (info), info->client_info.suspend_done, !sgen_is_thread_in_current_stw (info));
continue;
@ -438,7 +435,7 @@ sgen_unified_suspend_stop_world (void)
g_assert (!info->client_info.in_critical_region);
info->client_info.suspend_done = TRUE;
}
} END_FOREACH_THREAD_SAFE
} FOREACH_THREAD_END
if (restart_counter == 0)
break;
@ -456,19 +453,19 @@ sgen_unified_suspend_stop_world (void)
sleep_duration += 10;
}
FOREACH_THREAD_SAFE (info) {
FOREACH_THREAD (info) {
if (sgen_is_thread_in_current_stw (info) && mono_thread_info_is_running (info)) {
gboolean res = mono_thread_info_begin_suspend (info, FALSE);
THREADS_STW_DEBUG ("[GC-STW-RESTART] SUSPEND thread %p skip %d\n", mono_thread_info_get_tid (info), res);
if (!res)
info->client_info.skip = TRUE;
}
} END_FOREACH_THREAD_SAFE
} FOREACH_THREAD_END
mono_threads_wait_pending_operations ();
}
FOREACH_THREAD_SAFE (info) {
FOREACH_THREAD (info) {
if (sgen_is_thread_in_current_stw (info)) {
THREADS_STW_DEBUG ("[GC-STW-SUSPEND-END] thread %p is suspended\n", mono_thread_info_get_tid (info));
g_assert (info->client_info.suspend_done);
@ -476,23 +473,21 @@ sgen_unified_suspend_stop_world (void)
} else {
g_assert (!info->client_info.suspend_done || info == mono_thread_info_current ());
}
} END_FOREACH_THREAD_SAFE
} FOREACH_THREAD_END
}
static void
sgen_unified_suspend_restart_world (void)
{
SgenThreadInfo *info;
THREADS_STW_DEBUG ("[GC-STW-END] *** BEGIN RESUME ***\n");
FOREACH_THREAD_SAFE (info) {
FOREACH_THREAD (info) {
if (sgen_is_thread_in_current_stw (info)) {
g_assert (mono_thread_info_begin_resume (info));
THREADS_STW_DEBUG ("[GC-STW-RESUME-WORLD] RESUME thread %p\n", mono_thread_info_get_tid (info));
} else {
THREADS_STW_DEBUG ("[GC-STW-RESUME-WORLD] IGNORE thread %p\n", mono_thread_info_get_tid (info));
}
} END_FOREACH_THREAD_SAFE
} FOREACH_THREAD_END
mono_threads_wait_pending_operations ();
mono_threads_end_global_suspend ();

View File

@ -801,7 +801,7 @@ EXTRA_DIST = TestDriver.cs \
Makefile.am.in
version.h: Makefile
echo "#define FULL_VERSION \"Stable 4.3.2.467/ba2e5e4\"" > version.h
echo "#define FULL_VERSION \"Stable 4.4.0.40/f8474c4\"" > version.h
# Utility target for patching libtool to speed up linking
patch-libtool:

View File

@ -801,7 +801,7 @@ EXTRA_DIST = TestDriver.cs \
Makefile.am.in
version.h: Makefile
echo "#define FULL_VERSION \"Stable 4.3.2.467/ba2e5e4\"" > version.h
echo "#define FULL_VERSION \"Stable 4.4.0.40/f8474c4\"" > version.h
# Utility target for patching libtool to speed up linking
patch-libtool:

View File

@ -1 +1 @@
26c259ab73e00ef686162f329e573254e8a1a8be
feaddf3ea0bb6cd34b061a30d89031f0d11d66ec

View File

@ -1 +1 @@
91cb5ce5004d809c09f9c0d8a526f78070c03c8d
26979427a0ebbb4e979939dad6a0e766cc2b6917

View File

@ -1 +1 @@
13f9263e7cb11b6262697f85d44bc8d01a9ccd07
26d4d91456e706536c43cb083afe6adde5d651e0

View File

@ -262,7 +262,7 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot)
continue;
#endif
if (AMD64_IS_CALLEE_SAVED_REG (i) && i != AMD64_RBP)
amd64_mov_reg_membase (code, AMD64_RBX, AMD64_ARG_REG1, gregs_offset + (i * 8), 8);
amd64_mov_reg_membase (code, i, AMD64_ARG_REG1, gregs_offset + (i * 8), 8);
}
/* load exc register */
amd64_mov_reg_membase (code, AMD64_RAX, AMD64_ARG_REG1, gregs_offset + (AMD64_RAX * 8), 8);

View File

@ -12,6 +12,13 @@
#include "config.h"
#include <llvm-c/Core.h>
#include <llvm-c/ExecutionEngine.h>
#include "mini-llvm-cpp.h"
#if !defined(MONO_CROSS_COMPILE) && LLVM_API_VERSION < 100
#include <stdint.h>
#include <llvm/Support/raw_ostream.h>
@ -36,13 +43,6 @@
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/Module.h>
#include <llvm-c/Core.h>
#include <llvm-c/ExecutionEngine.h>
#include "mini-llvm-cpp.h"
#ifndef MONO_CROSS_COMPILE
using namespace llvm;
static void (*unhandled_exception)() = default_mono_llvm_unhandled_exception;

View File

@ -1 +1 @@
915dc58fe04dbc4ab7dd14806c61b46212a195f9
c4647d8650c5892dc0c3989cb5d74e993161ffcc

View File

@ -326,7 +326,6 @@ per_thread_profiler_hit (void *ctx)
MONO_SIG_HANDLER_FUNC (static, sigprof_signal_handler)
{
MonoThreadInfo *info;
int old_errno = errno;
int hp_save_index;
MONO_SIG_HANDLER_GET_CONTEXT;
@ -348,7 +347,7 @@ MONO_SIG_HANDLER_FUNC (static, sigprof_signal_handler)
mono_threads_add_async_job (info, MONO_SERVICE_REQUEST_SAMPLE);
mono_threads_pthread_kill (info, profiling_signal_in_use);
} END_FOREACH_THREAD_SAFE;
} FOREACH_THREAD_SAFE_END
}
mono_thread_info_set_is_async_context (TRUE);

View File

@ -1 +1 @@
#define FULL_VERSION "Stable 4.3.2.467/ba2e5e4"
#define FULL_VERSION "Stable 4.4.0.40/f8474c4"

View File

@ -530,15 +530,13 @@ sgen_init_tlab_info (SgenThreadInfo* info)
void
sgen_clear_tlabs (void)
{
SgenThreadInfo *info;
FOREACH_THREAD (info) {
/* A new TLAB will be allocated when the thread does its first allocation */
*info->tlab_start_addr = NULL;
*info->tlab_next_addr = NULL;
*info->tlab_temp_end_addr = NULL;
*info->tlab_real_end_addr = NULL;
} END_FOREACH_THREAD
} FOREACH_THREAD_END
}
void

View File

@ -505,7 +505,6 @@ find_pinning_ref_from_thread (char *obj, size_t size)
{
#ifndef SGEN_WITHOUT_MONO
int j;
SgenThreadInfo *info;
char *endobj = obj + size;
FOREACH_THREAD (info) {
@ -527,8 +526,8 @@ find_pinning_ref_from_thread (char *obj, size_t size)
if (w >= (mword)obj && w < (mword)obj + size)
SGEN_LOG (0, "Object %p referenced in saved reg %d of thread %p (id %p)", obj, j, info, (gpointer)mono_thread_info_get_tid (info));
} END_FOREACH_THREAD
}
} FOREACH_THREAD_END
#endif
}

View File

@ -74,11 +74,11 @@ worker (void *arg)
break;
case STATE_OUT:
if (InterlockedCompareExchange (&nodes [i].state, STATE_BUSY, STATE_OUT) == STATE_OUT) {
result = mono_lls_find (&lls, hp, i);
result = mono_lls_find (&lls, hp, i, HAZARD_FREE_SAFE_CTX);
assert (!result);
mono_hazard_pointer_clear_all (hp, -1);
result = mono_lls_insert (&lls, hp, &nodes [i].node);
result = mono_lls_insert (&lls, hp, &nodes [i].node, HAZARD_FREE_SAFE_CTX);
mono_hazard_pointer_clear_all (hp, -1);
assert (nodes [i].state == STATE_BUSY);
@ -89,12 +89,12 @@ worker (void *arg)
break;
case STATE_IN:
if (InterlockedCompareExchange (&nodes [i].state, STATE_BUSY, STATE_IN) == STATE_IN) {
result = mono_lls_find (&lls, hp, i);
result = mono_lls_find (&lls, hp, i, HAZARD_FREE_SAFE_CTX);
assert (result);
assert (mono_hazard_pointer_get_val (hp, 1) == &nodes [i].node);
mono_hazard_pointer_clear_all (hp, -1);
result = mono_lls_remove (&lls, hp, &nodes [i].node);
result = mono_lls_remove (&lls, hp, &nodes [i].node, HAZARD_FREE_SAFE_CTX);
mono_hazard_pointer_clear_all (hp, -1);
++thread_data->num_removes;
@ -126,7 +126,7 @@ main (int argc, char *argv [])
mono_threads_init (&thread_callbacks, 0);
mono_lls_init (&lls, free_node);
mono_lls_init (&lls, free_node, HAZARD_FREE_NO_LOCK);
for (i = 0; i < N; ++i) {
nodes [i].node.key = i;

View File

@ -28,7 +28,7 @@
typedef struct {
gpointer p;
MonoHazardousFreeFunc free_func;
gboolean might_lock;
HazardFreeLocking locking;
} DelayedFreeItem;
/* The hazard table */
@ -286,7 +286,7 @@ mono_hazard_pointer_restore_for_signal_handler (int small_id)
}
static gboolean
try_free_delayed_free_item (gboolean lock_free_context)
try_free_delayed_free_item (HazardFreeContext context)
{
DelayedFreeItem item;
gboolean popped = mono_lock_free_array_queue_pop (&delayed_free_queue, &item);
@ -294,7 +294,8 @@ try_free_delayed_free_item (gboolean lock_free_context)
if (!popped)
return FALSE;
if ((lock_free_context && item.might_lock) || (is_pointer_hazardous (item.p))) {
if ((context == HAZARD_FREE_ASYNC_CTX && item.locking == HAZARD_FREE_MAY_LOCK) ||
(is_pointer_hazardous (item.p))) {
mono_lock_free_array_queue_push (&delayed_free_queue, &item);
return FALSE;
}
@ -306,24 +307,20 @@ try_free_delayed_free_item (gboolean lock_free_context)
void
mono_thread_hazardous_free_or_queue (gpointer p, MonoHazardousFreeFunc free_func,
gboolean free_func_might_lock, gboolean lock_free_context)
HazardFreeLocking locking, HazardFreeContext context)
{
int i;
if (lock_free_context)
g_assert (!free_func_might_lock);
if (free_func_might_lock)
g_assert (!lock_free_context);
/* First try to free a few entries in the delayed free
table. */
for (i = 0; i < 3; ++i)
try_free_delayed_free_item (lock_free_context);
try_free_delayed_free_item (context);
/* Now see if the pointer we're freeing is hazardous. If it
isn't, free it. Otherwise put it in the delay list. */
if (is_pointer_hazardous (p)) {
DelayedFreeItem item = { p, free_func, free_func_might_lock };
if ((context == HAZARD_FREE_ASYNC_CTX && locking == HAZARD_FREE_MAY_LOCK) ||
is_pointer_hazardous (p)) {
DelayedFreeItem item = { p, free_func, locking };
++hazardous_pointer_count;
@ -336,7 +333,7 @@ mono_thread_hazardous_free_or_queue (gpointer p, MonoHazardousFreeFunc free_func
void
mono_thread_hazardous_try_free_all (void)
{
while (try_free_delayed_free_item (FALSE))
while (try_free_delayed_free_item (HAZARD_FREE_SAFE_CTX))
;
}
@ -345,7 +342,7 @@ mono_thread_hazardous_try_free_some (void)
{
int i;
for (i = 0; i < 10; ++i)
try_free_delayed_free_item (FALSE);
try_free_delayed_free_item (HAZARD_FREE_SAFE_CTX);
}
void

View File

@ -18,8 +18,18 @@ typedef struct {
typedef void (*MonoHazardousFreeFunc) (gpointer p);
typedef enum {
HAZARD_FREE_MAY_LOCK,
HAZARD_FREE_NO_LOCK,
} HazardFreeLocking;
typedef enum {
HAZARD_FREE_SAFE_CTX,
HAZARD_FREE_ASYNC_CTX,
} HazardFreeContext;
void mono_thread_hazardous_free_or_queue (gpointer p, MonoHazardousFreeFunc free_func,
gboolean free_func_might_lock, gboolean lock_free_context);
HazardFreeLocking locking, HazardFreeContext context);
void mono_thread_hazardous_try_free_all (void);
void mono_thread_hazardous_try_free_some (void);
MonoThreadHazardPointers* mono_hazard_pointer_get (void);

View File

@ -250,7 +250,7 @@ desc_retire (Descriptor *desc)
g_assert (desc->in_use);
desc->in_use = FALSE;
free_sb (desc->sb, desc->block_size);
mono_thread_hazardous_free_or_queue (desc, desc_enqueue_avail, FALSE, TRUE);
mono_thread_hazardous_free_or_queue (desc, desc_enqueue_avail, HAZARD_FREE_NO_LOCK, HAZARD_FREE_ASYNC_CTX);
}
#else
MonoLockFreeQueue available_descs;
@ -302,7 +302,7 @@ static void
list_put_partial (Descriptor *desc)
{
g_assert (desc->anchor.data.state != STATE_FULL);
mono_thread_hazardous_free_or_queue (desc, desc_put_partial, FALSE, TRUE);
mono_thread_hazardous_free_or_queue (desc, desc_put_partial, HAZARD_FREE_NO_LOCK, HAZARD_FREE_ASYNC_CTX);
}
static void
@ -321,7 +321,7 @@ list_remove_empty_desc (MonoLockFreeAllocSizeClass *sc)
desc_retire (desc);
} else {
g_assert (desc->heap->sc == sc);
mono_thread_hazardous_free_or_queue (desc, desc_put_partial, FALSE, TRUE);
mono_thread_hazardous_free_or_queue (desc, desc_put_partial, HAZARD_FREE_NO_LOCK, HAZARD_FREE_ASYNC_CTX);
if (++num_non_empty >= 2)
return;
}

View File

@ -286,7 +286,7 @@ mono_lock_free_queue_dequeue (MonoLockFreeQueue *q)
g_assert (q->has_dummy);
q->has_dummy = 0;
mono_memory_write_barrier ();
mono_thread_hazardous_free_or_queue (head, free_dummy, FALSE, TRUE);
mono_thread_hazardous_free_or_queue (head, free_dummy, HAZARD_FREE_NO_LOCK, HAZARD_FREE_ASYNC_CTX);
if (try_reenqueue_dummy (q))
goto retry;
return NULL;

View File

@ -56,7 +56,7 @@ conc_table_free (gpointer ptr)
static void
conc_table_lf_free (conc_table *table)
{
mono_thread_hazardous_free_or_queue (table, conc_table_free, TRUE, FALSE);
mono_thread_hazardous_free_or_queue (table, conc_table_free, HAZARD_FREE_MAY_LOCK, HAZARD_FREE_SAFE_CTX);
}

View File

@ -56,27 +56,28 @@ get_hazardous_pointer_with_mask (gpointer volatile *pp, MonoThreadHazardPointers
/*
Initialize @list and will use @free_node_func to release memory.
If @free_node_func is null the caller is responsible for releasing node memory.
@free_node_func must be lock-free. That implies that it cannot use malloc/free.
If @free_node_func may lock, @free_node_func_locking must be
HAZARD_FREE_MAY_LOCK; otherwise, HAZARD_FREE_NO_LOCK. It is ignored if
@free_node_func is null.
*/
void
mono_lls_init (MonoLinkedListSet *list, void (*free_node_func)(void *))
mono_lls_init (MonoLinkedListSet *list, void (*free_node_func)(void *), HazardFreeLocking free_node_func_locking)
{
list->head = NULL;
list->free_node_func = free_node_func;
list->locking = free_node_func_locking;
}
/*
Search @list for element with key @key.
@context specifies whether the function is being called from a lock-free (i.e.
signal handler or world stopped) context. It is only relevant if a node free
function was given.
The nodes next, cur and prev are returned in @hp.
Returns true if a node with key @key was found.
This function cannot be called from a signal nor within interrupt context*.
XXX A variant that works within interrupted is possible if needed.
* interrupt context is when the current thread is reposible for another thread
been suspended at an arbritary point. This is a limitation of our SMR implementation.
*/
gboolean
mono_lls_find (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, uintptr_t key)
mono_lls_find (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, uintptr_t key, HazardFreeContext context)
{
MonoLinkedListSetNode *cur, *next;
MonoLinkedListSetNode **prev;
@ -125,7 +126,7 @@ try_again:
mono_memory_write_barrier ();
mono_hazard_pointer_clear (hp, 1);
if (list->free_node_func)
mono_thread_hazardous_free_or_queue (cur, list->free_node_func, FALSE, TRUE);
mono_thread_hazardous_free_or_queue (cur, list->free_node_func, list->locking, context);
} else
goto try_again;
}
@ -136,13 +137,15 @@ try_again:
/*
Insert @value into @list.
@context specifies whether the function is being called from a lock-free (i.e.
signal handler or world stopped) context. It is only relevant if a node free
function was given.
The nodes value, cur and prev are returned in @hp.
Return true if @value was inserted by this call. If it returns FALSE, it's the caller
resposibility to release memory.
This function cannot be called from a signal nor with the world stopped.
*/
gboolean
mono_lls_insert (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value)
mono_lls_insert (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value, HazardFreeContext context)
{
MonoLinkedListSetNode *cur, **prev;
/*We must do a store barrier before inserting
@ -150,7 +153,7 @@ mono_lls_insert (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLink
mono_memory_barrier ();
while (1) {
if (mono_lls_find (list, hp, value->key))
if (mono_lls_find (list, hp, value->key, context))
return FALSE;
cur = (MonoLinkedListSetNode *) mono_hazard_pointer_get_val (hp, 1);
prev = (MonoLinkedListSetNode **) mono_hazard_pointer_get_val (hp, 2);
@ -165,17 +168,19 @@ mono_lls_insert (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLink
}
/*
Search @list for element with key @key.
Search @list for element with key @key and remove it.
@context specifies whether the function is being called from a lock-free (i.e.
signal handler or world stopped) context. It is only relevant if a node free
function was given.
The nodes next, cur and prev are returned in @hp
Returns true if @value was removed by this call.
This function cannot be called from a signal nor with the world stopped.
*/
gboolean
mono_lls_remove (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value)
mono_lls_remove (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value, HazardFreeContext context)
{
MonoLinkedListSetNode *cur, **prev, *next;
while (1) {
if (!mono_lls_find (list, hp, value->key))
if (!mono_lls_find (list, hp, value->key, context))
return FALSE;
next = (MonoLinkedListSetNode *) mono_hazard_pointer_get_val (hp, 0);
@ -193,9 +198,9 @@ mono_lls_remove (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLink
mono_memory_write_barrier ();
mono_hazard_pointer_clear (hp, 1);
if (list->free_node_func)
mono_thread_hazardous_free_or_queue (value, list->free_node_func, FALSE, TRUE);
mono_thread_hazardous_free_or_queue (value, list->free_node_func, list->locking, context);
} else
mono_lls_find (list, hp, value->key);
mono_lls_find (list, hp, value->key, context);
return TRUE;
}
}

View File

@ -24,6 +24,7 @@ struct _MonoLinkedListSetNode {
typedef struct {
MonoLinkedListSetNode *head;
void (*free_node_func)(void *);
HazardFreeLocking locking;
} MonoLinkedListSet;
@ -45,77 +46,129 @@ You must manually clean the hazard pointer table after using them.
*/
void
mono_lls_init (MonoLinkedListSet *list, void (*free_node_func)(void *));
mono_lls_init (MonoLinkedListSet *list, void (*free_node_func)(void *), HazardFreeLocking free_node_func_locking);
gboolean
mono_lls_find (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, uintptr_t key);
mono_lls_find (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, uintptr_t key, HazardFreeContext context);
gboolean
mono_lls_insert (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value);
mono_lls_insert (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value, HazardFreeContext context);
gboolean
mono_lls_remove (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value);
mono_lls_remove (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value, HazardFreeContext context);
gpointer
get_hazardous_pointer_with_mask (gpointer volatile *pp, MonoThreadHazardPointers *hp, int hazard_index);
/*
Requires the world to be stoped
*/
#define MONO_LLS_FOREACH(list, element, type) {\
MonoLinkedListSetNode *__cur; \
for (__cur = (list)->head; __cur; __cur = mono_lls_pointer_unmask (__cur->next)) \
if (!mono_lls_pointer_get_mark (__cur->next)) { \
(element) = (type)__cur;
#define MONO_LLS_FOREACH_FILTERED(list, element, filter_func, type) {\
MonoLinkedListSetNode *__cur; \
for (__cur = (list)->head; __cur; __cur = (MonoLinkedListSetNode *)mono_lls_pointer_unmask (__cur->next)) \
if (!mono_lls_pointer_get_mark (__cur->next)) { \
(element) = (type)__cur; \
if (!filter_func (element)) continue;
#define MONO_LLS_END_FOREACH }}
static inline MonoLinkedListSetNode*
mono_lls_info_step (MonoLinkedListSetNode *val, MonoThreadHazardPointers *hp)
static inline gboolean
mono_lls_filter_accept_all (gpointer elem)
{
val = (MonoLinkedListSetNode *) mono_lls_pointer_unmask (val);
mono_hazard_pointer_set (hp, 1, val);
return val;
return TRUE;
}
/*
Provides snapshot iteration
* These macros assume that no other threads are actively modifying the list.
*/
#define MONO_LLS_FOREACH_SAFE(list, element, type) {\
MonoThreadHazardPointers *__hp = mono_hazard_pointer_get (); \
MonoLinkedListSetNode *__cur, *__next; \
for (__cur = (MonoLinkedListSetNode *) mono_lls_pointer_unmask (get_hazardous_pointer ((gpointer volatile*)&(list)->head, __hp, 1)); \
__cur; \
__cur = (MonoLinkedListSetNode *) mono_lls_info_step (__next, __hp)) { \
__next = (MonoLinkedListSetNode *) get_hazardous_pointer_with_mask ((gpointer volatile*)&__cur->next, __hp, 0); \
if (!mono_lls_pointer_get_mark (__next)) { \
(element) = (type)__cur;
#define MONO_LLS_FOREACH_FILTERED_SAFE(list, element, filter_func, type) {\
MonoThreadHazardPointers *__hp = mono_hazard_pointer_get (); \
MonoLinkedListSetNode *__cur, *__next; \
for (__cur = (MonoLinkedListSetNode *) mono_lls_pointer_unmask (get_hazardous_pointer ((gpointer volatile*)&(list)->head, __hp, 1)); \
__cur; \
__cur = (MonoLinkedListSetNode *) mono_lls_info_step (__next, __hp)) { \
__next = (MonoLinkedListSetNode *) get_hazardous_pointer_with_mask ((gpointer volatile*)&__cur->next, __hp, 0); \
if (!mono_lls_pointer_get_mark (__next)) { \
(element) = (type)__cur; \
if (!filter_func (element)) continue;
#define MONO_LLS_FOREACH_FILTERED(list, type, elem, filter) \
do { \
MonoLinkedListSet *list__ = (list); \
for (MonoLinkedListSetNode *cur__ = list__->head; cur__; cur__ = (MonoLinkedListSetNode *) mono_lls_pointer_unmask (cur__->next)) { \
if (!mono_lls_pointer_get_mark (cur__->next)) { \
type *elem = (type *) cur__; \
if (filter (elem)) {
#define MONO_LLS_END_FOREACH_SAFE \
#define MONO_LLS_FOREACH_END \
} \
} \
mono_hazard_pointer_clear (__hp, 0); \
mono_hazard_pointer_clear (__hp, 1); \
}
} \
} while (0);
#define MONO_LLS_FOREACH(list, type, elem) \
MONO_LLS_FOREACH_FILTERED ((list), type, elem, mono_lls_filter_accept_all)
/*
* These macros can be used while other threads are potentially modifying the
* list, but they only provide a snapshot of the list as a result.
*
* NOTE: Do NOT break out of the loop through any other means than a break
* statement, as other ways of breaking the loop will skip past important
* cleanup work.
*/
#define MONO_LLS_FOREACH_FILTERED_SAFE(list, type, elem, filter) \
do { \
/* NOTE: Keep this macro's code in sync with the mono_lls_find () logic. */ \
MonoLinkedListSet *list__ = (list); \
MonoThreadHazardPointers *hp__ = mono_hazard_pointer_get (); \
gboolean progress__ = FALSE; \
uintptr_t hkey__; \
gboolean restart__; \
do { \
restart__ = FALSE; \
MonoLinkedListSetNode **prev__ = &list__->head; \
mono_hazard_pointer_set (hp__, 2, prev__); \
MonoLinkedListSetNode *cur__ = (MonoLinkedListSetNode *) get_hazardous_pointer_with_mask ((gpointer *) prev__, hp__, 1); \
while (1) { \
if (!cur__) { \
break; \
} \
MonoLinkedListSetNode *next__ = (MonoLinkedListSetNode *) get_hazardous_pointer_with_mask ((gpointer *) &cur__->next, hp__, 0); \
uintptr_t ckey__ = cur__->key; \
mono_memory_read_barrier (); \
if (*prev__ != cur__) { \
restart__ = TRUE; \
break; \
} \
if (!mono_lls_pointer_get_mark (next__)) { \
if (!progress__ || ckey__ > hkey__) { \
progress__ = TRUE; \
hkey__ = ckey__; \
type *elem = (type *) cur__; \
if (filter (elem)) { \
gboolean broke__ = TRUE; \
gboolean done__ = FALSE; \
do { \
if (done__) { \
broke__ = FALSE; \
break; \
} \
done__ = TRUE;
#define MONO_LLS_FOREACH_SAFE_END \
broke__ = FALSE; \
break; \
} while (1); \
if (broke__) { \
break; \
} \
} \
} \
prev__ = &cur__->next; \
mono_hazard_pointer_set (hp__, 2, cur__); \
} else { \
next__ = (MonoLinkedListSetNode *) mono_lls_pointer_unmask (next__); \
if (InterlockedCompareExchangePointer ((volatile gpointer *) prev__, next__, cur__) == cur__) { \
mono_memory_write_barrier (); \
mono_hazard_pointer_clear (hp__, 1); \
if (list__->free_node_func) { \
mono_thread_hazardous_free_or_queue (cur__, list__->free_node_func, list__->locking, HAZARD_FREE_ASYNC_CTX); \
} \
} else { \
restart__ = TRUE; \
break; \
} \
} \
cur__ = (MonoLinkedListSetNode *) mono_lls_pointer_unmask (next__); \
mono_hazard_pointer_set (hp__, 1, cur__); \
} \
} while (restart__); \
mono_hazard_pointer_clear (hp__, 0); \
mono_hazard_pointer_clear (hp__, 1); \
mono_hazard_pointer_clear (hp__, 2); \
} while (0);
#define MONO_LLS_FOREACH_SAFE(list, type, elem) \
MONO_LLS_FOREACH_FILTERED_SAFE ((list), type, elem, mono_lls_filter_accept_all)
#endif /* __MONO_SPLIT_ORDERED_LIST_H__ */

View File

@ -187,7 +187,6 @@ mono_threads_end_global_suspend (void)
static void
dump_threads (void)
{
MonoThreadInfo *info;
MonoThreadInfo *cur = mono_thread_info_current ();
MOSTLY_ASYNC_SAFE_PRINTF ("STATE CUE CARD: (? means a positive number, usually 1 or 2, * means any number)\n");
@ -210,8 +209,7 @@ dump_threads (void)
#else
MOSTLY_ASYNC_SAFE_PRINTF ("--thread %p id %p [%p] state %x %s\n", info, (void *) mono_thread_info_get_tid (info), (void*)(size_t)info->native_handle, info->thread_state, info == cur ? "GC INITIATOR" : "" );
#endif
} END_FOREACH_THREAD_SAFE
} FOREACH_THREAD_SAFE_END
}
gboolean
@ -271,7 +269,7 @@ mono_thread_info_lookup (MonoNativeThreadId id)
{
MonoThreadHazardPointers *hp = mono_hazard_pointer_get ();
if (!mono_lls_find (&thread_list, hp, (uintptr_t)id)) {
if (!mono_lls_find (&thread_list, hp, (uintptr_t)id, HAZARD_FREE_ASYNC_CTX)) {
mono_hazard_pointer_clear_all (hp, -1);
return NULL;
}
@ -285,7 +283,7 @@ mono_thread_info_insert (MonoThreadInfo *info)
{
MonoThreadHazardPointers *hp = mono_hazard_pointer_get ();
if (!mono_lls_insert (&thread_list, hp, (MonoLinkedListSetNode*)info)) {
if (!mono_lls_insert (&thread_list, hp, (MonoLinkedListSetNode*)info, HAZARD_FREE_SAFE_CTX)) {
mono_hazard_pointer_clear_all (hp, -1);
return FALSE;
}
@ -301,7 +299,7 @@ mono_thread_info_remove (MonoThreadInfo *info)
gboolean res;
THREADS_DEBUG ("removing info %p\n", info);
res = mono_lls_remove (&thread_list, hp, (MonoLinkedListSetNode*)info);
res = mono_lls_remove (&thread_list, hp, (MonoLinkedListSetNode*)info, HAZARD_FREE_SAFE_CTX);
mono_hazard_pointer_clear_all (hp, -1);
return res;
}
@ -426,7 +424,7 @@ unregister_thread (void *arg)
g_byte_array_free (info->stackdata, /*free_segment=*/TRUE);
/*now it's safe to free the thread info.*/
mono_thread_hazardous_free_or_queue (info, free_thread_info, TRUE, FALSE);
mono_thread_hazardous_free_or_queue (info, free_thread_info, HAZARD_FREE_MAY_LOCK, HAZARD_FREE_SAFE_CTX);
mono_thread_small_id_free (small_id);
}
@ -637,7 +635,7 @@ mono_threads_init (MonoThreadInfoCallbacks *callbacks, size_t info_size)
mono_coop_sem_init (&global_suspend_semaphore, 1);
mono_os_sem_init (&suspend_semaphore, 0);
mono_lls_init (&thread_list, NULL);
mono_lls_init (&thread_list, NULL, HAZARD_FREE_NO_LOCK);
mono_thread_smr_init ();
mono_threads_init_platform ();
mono_threads_init_coop ();
@ -1124,35 +1122,35 @@ sleep_interrupt (gpointer data)
static inline guint32
sleep_interruptable (guint32 ms, gboolean *alerted)
{
guint32 start, now, end;
gint64 now, end;
g_assert (INFINITE == G_MAXUINT32);
g_assert (alerted);
*alerted = FALSE;
start = mono_msec_ticks ();
if (start < G_MAXUINT32 - ms) {
end = start + ms;
} else {
/* start + ms would overflow guint32 */
end = G_MAXUINT32;
}
if (ms != INFINITE)
end = mono_100ns_ticks () + (ms * 1000 * 10);
mono_lazy_initialize (&sleep_init, sleep_initialize);
mono_coop_mutex_lock (&sleep_mutex);
for (now = mono_msec_ticks (); ms == INFINITE || now - start < ms; now = mono_msec_ticks ()) {
for (;;) {
if (ms != INFINITE) {
now = mono_100ns_ticks ();
if (now > end)
break;
}
mono_thread_info_install_interrupt (sleep_interrupt, NULL, alerted);
if (*alerted) {
mono_coop_mutex_unlock (&sleep_mutex);
return WAIT_IO_COMPLETION;
}
if (ms < INFINITE)
mono_coop_cond_timedwait (&sleep_cond, &sleep_mutex, end - now);
if (ms != INFINITE)
mono_coop_cond_timedwait (&sleep_cond, &sleep_mutex, (end - now) / 10 / 1000);
else
mono_coop_cond_wait (&sleep_cond, &sleep_mutex);

View File

@ -297,14 +297,20 @@ mono_threads_filter_tools_threads (THREAD_INFO_TYPE *info)
/*
Requires the world to be stoped
*/
#define FOREACH_THREAD(thread) MONO_LLS_FOREACH_FILTERED (mono_thread_info_list_head (), thread, mono_threads_filter_tools_threads, THREAD_INFO_TYPE*)
#define END_FOREACH_THREAD MONO_LLS_END_FOREACH
#define FOREACH_THREAD(thread) \
MONO_LLS_FOREACH_FILTERED (mono_thread_info_list_head (), THREAD_INFO_TYPE, thread, mono_threads_filter_tools_threads)
#define FOREACH_THREAD_END \
MONO_LLS_FOREACH_END
/*
Snapshot iteration.
*/
#define FOREACH_THREAD_SAFE(thread) MONO_LLS_FOREACH_FILTERED_SAFE (mono_thread_info_list_head (), thread, mono_threads_filter_tools_threads, THREAD_INFO_TYPE*)
#define END_FOREACH_THREAD_SAFE MONO_LLS_END_FOREACH_SAFE
#define FOREACH_THREAD_SAFE(thread) \
MONO_LLS_FOREACH_FILTERED_SAFE (mono_thread_info_list_head (), THREAD_INFO_TYPE, thread, mono_threads_filter_tools_threads)
#define FOREACH_THREAD_SAFE_END \
MONO_LLS_FOREACH_SAFE_END
static inline MonoNativeThreadId
mono_thread_info_get_tid (THREAD_INFO_TYPE *info)

View File

@ -4,7 +4,7 @@ if exist config.h if not exist cygconfig.h copy config.h cygconfig.h
if exist eglib\config.h if not exist eglib\cygconfig.h copy eglib\config.h eglib\cygconfig.h
copy winconfig.h config.h
copy eglib\winconfig.h eglib\config.h
powershell -Command "(Get-Content config.h) -replace '#MONO_VERSION#', (Select-String -path configure.ac -pattern 'AC_INIT\(mono, \[(.*)\]').Matches[0].Groups[1].Value | Set-Content config.h"
%windir%\system32\WindowsPowerShell\v1.0\powershell.exe -Command "(Get-Content config.h) -replace '#MONO_VERSION#', (Select-String -path configure.ac -pattern 'AC_INIT\(mono, \[(.*)\]').Matches[0].Groups[1].Value | Set-Content config.h"
goto end
:error
echo fatal error: the VSDepenancies directory was not found in the "mono" directory

Binary file not shown.

View File

@ -1 +1 @@
56caa8e71219b6c821001eea2e6bf991bfeb90ef
dcc0bb17a9a21c5af4bb5f5ae2d9ee003e4b0be6

Some files were not shown because too many files have changed in this diff Show More