This is an interesting issue that happens in the following scenario:
1. A request is performed that will take some extra time to get a
response or an error.
2. The request is cancelled BEFORE the delegate methods
DidReceiveResponse, DidReceiveData or DidCompleteWithError and
called. Yet we have not yet fully canceled the native request. It
does take some time to do so, that is why we have a
'NSURLSessionTaskStateCanceling' and not 'NSURLSessionTaskStateCancelled'
The issue happens because the GetInflightData checks if the task has
been canceled. In that method we have the following:
```csharp
if (inflight.CancellationToken.IsCancellationRequested)
task?.Cancel ();
return inflight;
```
The call of the Cancel method in the NSData task has as ripple effect which
is the execution of the following callback:
```csharp
cancellationToken.Register (() => {
RemoveInflightData (dataTask);
tcs.TrySetCanceled ();
});
```
Which calls:
```csharp
void RemoveInflightData (NSUrlSessionTask task, bool cancel = true)
{
lock (inflightRequestsLock) {
if (inflightRequests.TryGetValue (task, out var data)) {
if (cancel)
data.CancellationTokenSource.Cancel ();
data.Dispose ();
inflightRequests.Remove (task);
}
// do we need to be notified? If we have not inflightData, we do not
if (inflightRequests.Count == 0)
RemoveNotification ();
}
if (cancel)
task?.Cancel ();
task?.Dispose ();
}
```
The above call does call Dispose and Dipose in the inflight data does:
```csharp
if (disposing) {
if (CancellationTokenSource != null) {
CancellationTokenSource.Dispose ();
CancellationTokenSource = null;
}
}
```
If we follow these set of events for example in the
DidRecieveResponse:
```chsarp
[Preserve (Conditional = true)]
public override void DidReceiveResponse (NSUrlSession session, NSUrlSessionDataTask dataTask, NSUrlResponse response, Action<NSUrlSessionResponseDisposition> completionHandler)
{
var inflight = GetInflightData (dataTask);
if (inflight == null)
return;
try {
var urlResponse = (NSHttpUrlResponse)response;
var status = (int)urlResponse.StatusCode;
var content = new NSUrlSessionDataTaskStreamContent (inflight.Stream, () => {
if (!inflight.Completed) {
dataTask.Cancel ();
}
inflight.Disposed = true;
inflight.Stream.TrySetException (new ObjectDisposedException ("The content stream was disposed."));
sessionHandler.RemoveInflightData (dataTask);
}, inflight.CancellationTokenSource.Token);
```
If can happen that, when we get the delegate call to the method, the
request has been cancelled. That means that we are in the precise state
in which we do not longer care about the response BUT we did get a
infligh data reference.. that HAS BEEN DIPOSED!!! this later gives a NRE
in several places.
The correct way is to return null from the GetInflighData method if we
have been cancelled, this makes sense because if we cancelled we do not
care about the execution of any of the methods that required the data
since it has been disposed!
Co-authored-by: Rolf Bjarne Kvinge <rolf@xamarin.com>
Xamarin.MacCatalyst ships a `Xamarin.iOS.dll` assembly that contains
forwarders (to `Xamarin.MacCatalyst.dll`) and stubs that throws
`PlatformNotSupportedException`.
This is used to help code compatibility between both platforms - but
that requires exposing an identical surface and the best way to ensure
this is to compare (and report) them using `apidiff`
Co-authored-by: Manuel de la Pena <mandel@microsoft.com>
We need to call coreclr_initialize/monovm_initialize at startup, so do that.
This is a partial implementation, in that we're not setting all the properties
that we should, and also the PINVOKE_OVERRIDE callback is not doing everything
it should either yet.
Ref: #10504.
Backport several fixes in the CI into xcode12.5 to be able to do the
following:
- Get device tests.
- Get older mac executions.
Includes a needed bump of maccore:
* [d16-9] [CI] remove login keychain password and xqa cert passwords (#2410)
The way that CoreiOSSdkDirectory was definded ($(MSBuildThisFileDirectory.Replace('...', '...'))) was returning an encoded string value that caused issues in legacy project systems. The reason of the issues is that the CoreiOSSdkDirectory value for legacy project systems is `Program Files (x86)`, and the "Replace'" function was encoding the '(' and ')' causing the "UsingTask" for fail because the Assembly File path was wrong (because it contains those encoding values).
The fix consist of applying the "Replace" function only when the path of the targets belongs to a .net SDK path, in which case it won't fail because it's under "Program Files".
We need to discuss with the MSBuild team to show this issue and know if it's a bug or how we can avoid the failure
iOS Binding projects were not building remotely since 16.9. This commit fixes that and allows to start building remotely.
Xamarin.iOS.ObjCBinding.CSharp.After.props is imported too early and because it was also importing the Messaging targets, some things like RebuildDependsOn and BuildDependsOn were being overridden by other targets, resulting on not hooking up on the remote execution.
Add support for parsing --setenv from bundler arguments and passing them to
dotnet-linker so that the environment variables can be baked into the app at
launch (like they would be for mtouch/mmp).
* [runtime] Download the CoreCLR embedding header file
* [runtime] Create VM-specific code and header files and include them in the build
* [runtime] Move MonoVM-specific initialization to MonoVM-specific code.
* Add support for Xamarin.Mac arm64
* Add compile product definition task
Xamarin.Mac can be provided with a ProductDefinition file for the generated pkg. Normally, providing a product definition was optional. However, with Apple Silicon, we have an extra issue : `productbuild` needs to know what architectures your package target. If not provided with them, it will guess to the best of its abilities. However, on Catalina and lower, the guess is x86_64, even if you have an arm64 slice. To fix this, we add a new task to compile the product definition and use this file to create the pkg. If you provide your own Product Definition, we can check and warn if the architectures don't match what we expect. If the file doesn't exist or there is no architecture, we set it ourselves based on our target architectures.
* Don't reference dynamic objC_send on arm64
When building in debug, we currently try to link dynamic objC_send symbols when targeting a 64-bit architecture. However, this is actually only defined on Intel architectures, not on arm64, so we end up failing because we're referring symbols that don't exist. Rework the `GetRequiredSymbols` to take an abi, and tag those symbols to only be valid on i386/x86_64, so they don't get referred at all when building on arm64, but still get referred in x86_64.
* Fix improper delete/move with already existing directories
* Fix stret requirement for Xamarin.Mac in arm64.
The generator supposes that we're running in x64 mode, refactor to take into account the possibility of running in arm64.
* Implement OS version generation in Product.plist, based on MinimumSystemVersion of the app
* Re-generalize some mmp registrar rules
`Microsoft.macOS.registrar` was missed by the current rule set
* Fix mmp tests
* Set E7072 as not translated
Tests were failing otherwise
* Rename Xamarin.Mac lib/x86_64 folder to 64bits (currently all targeted archs are the same)
* Fix style issues
* Fix `ToLower` usage for invariant usage
* Fix xtro-sharpie test
* [tests] Don't forcefully exit macOS tests.
Instead give the process a chance to exist (3 seconds), before we take drastic
measures.
* Bump Touch.Unit.
New commits in spouliot/Touch.Unit:
* spouliot/Touch.Unit@f19eb45 [TouchRunner] Try to make MacRunner exit nicely. (#100)
Diff: a33e0c3f2e..f19eb45cb6
* It looks like mono from 2020-02 doesn't want to exit no matter what, so limit this to .NET.
* Remove references to the login keychaintools/devops/automation/templates/build/build.yml
* remove login-keychain envvar, add credential envvars
* use special branch of maccore
* Fix variable references
* Add keyringPass back in
* and here, too
* Change maccore to HEAD of current needed version + keychain fixes
* Bump back to maccore/main.
New commits in xamarin/maccore:
* xamarin/maccore@e81fac5451 [CI] remove login keychain password and xqa cert passwords (#2404)
* xamarin/maccore@548fa45432 [mlaunch] Disable building mlaunch when not including the legacy Xamarin build. (#2403)
Removed commits from xamarin/maccore:
* xamarin/maccore@ef5502ee51 remove login keychain password and xqa cert passwords
Diff: ef5502ee51..e81fac5451
* revert pipeline branch of maccore to main
* [maccore] Bump maccore
New commits in xamarin/maccore:
* xamarin/maccore@b9aaee7254 Remove unneeded block intended to add creds to login.keychain
* xamarin/maccore@0ac61f1fba [dotnet] Changes the msbuild.zip to include Windows files (#2408)
* xamarin/maccore@e81fac5451 [CI] remove login keychain password and xqa cert passwords (#2404)
Diff: 548fa45432..b9aaee7254
Co-authored-by: Rolf Bjarne Kvinge <rolf@xamarin.com>
Co-authored-by: Alex Soto <alex@alexsoto.me>
Previously, the SuperHandle property returned a pointer into the middle of the
NSObject instance. This is not safe, because we can't make pin the NSObject
instance past the return of the SuperHandle property getter.
So rework the logic, to allocate a chunk of native memory that SuperHandle can
return, and use that instead. This means a little bit of book-keeping to
create and destroy this native memory.
Unfortunately it will also increase the memory usage for each NSObject
instance, but I don't see a way around that, while still fixing the problem
with SuperHandle, given that we can't change the signature of SuperHandle.
The test run can fail even if all the tests pass: in case the process crashes
or deadlocks at exit for instance. Don't overwrite such failures with the unit
test results.
Co-authored-by: TJ Lambert <tjlambert@microsoft.com>
Co-authored-by: Alex Soto <alex@alexsoto.me>
Co-authored-by: Manuel de la Pena <mandel@microsoft.com>
This fixes almost [1] all `extra` API detected from the extrospection
(header-based) tests for MacCatalyst. This is needed to complete the
introspection fixes (without having _too large PR).
[1] except `!extra-null-allowed!` since those are still in progress for
all platforms
Use a private property (prefixed with underscore) for now, until we can decide
on a better/general name.
Also add a variation to xharness to build monotouch-test with CoreCLR
(building works fine, but it crashes at startup, which is expected at this
point).
* [tests] Preserve all test fixtures.
This fixes the wildly diffetent number of tests when running xammac tests with and without linking.
Without linking:
> Tests run: 2446 Passed: 2321 Inconclusive: 9 Failed: 0 Ignored: 125
vs with linking:
> Tests run: 1885 Passed: 1802 Inconclusive: 4 Failed: 0 Ignored: 83
Now we run the same tests either with or without linking.
One test was updated to not fail when linking is enabled.
Also add a test to ensure all future test fixtures are preserved.
* Remove whitespace noise.
The API were already available (iOS) and this helps fixing tests for
MacCatalyst (as it's based on our iOS API but expose the same issue
as macOS wrt extra ctor/init).
Move the creation of an uninitialized NSObject from native to managed, which:
* Removes the need for the mono_object_new Embedding API.
* Removes one location where we write to managed memory from native code (to
write the handle + flags in the uninitialized NSObject).
* Makes things easier for CoreCLR.