public Task WriteFragmentAsync(ArraySegment <byte> buffer, bool isUtf8Encoded, bool isFinalFragment)
        {
            TaskCompletionSource <object> tcs = new TaskCompletionSource <object>();

            // The buffer will be read from asynchronously by unmanaged code, so we require that it remain pinned
            PinnedArraySegment <byte> pinnedBuffer = new PinnedArraySegment <byte>(buffer);

            // Callback will always be called (since it is responsible for cleanup), even if completed synchronously
            CompletionCallback callback = (hrError, cbIO, fUtf8Encoded, fFinalFragment, fClose) => {
                try {
                    ThrowExceptionForHR(hrError);
                    tcs.TrySetResult(null); // regular completion
                }
                catch (Exception ex) {
                    tcs.TrySetException(ex); // exceptional completion
                }
                finally {
                    // Always free the buffer to prevent a memory leak
                    pinnedBuffer.Dispose();
                }
            };
            IntPtr completionContext = GCUtil.RootObject(callback);

            // update perf counter with count of data written to wire
            _perfCounters.IncrementCounter(AppPerfCounter.REQUEST_BYTES_OUT_WEBSOCKETS, pinnedBuffer.Count);

            // Call the underlying implementation; WriteFragment should never throw an exception
            int  bytesSent = pinnedBuffer.Count;
            bool completionExpected;
            int  hr = _context.WriteFragment(
                pData: pinnedBuffer.Pointer,
                pcbSent: ref bytesSent,
                fAsync: true,
                fUtf8Encoded: isUtf8Encoded,
                fFinalFragment: isFinalFragment,
                pfnCompletion: _asyncThunkAddress,
                pvCompletionContext: completionContext,
                pfCompletionExpected: out completionExpected);

            if (!completionExpected)
            {
                // Completed synchronously or error; the thunk and callback together handle cleanup
                AsyncCallbackThunk(hr, completionContext, bytesSent, isUtf8Encoded, isFinalFragment, fClose: false);
            }

            return(tcs.Task);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Runs as java pass through.
        /// </summary>
        /// <param name="callingFrame">The calling frame.</param>
        /// <param name="service">The service.</param>
        /// <param name="list">The list.</param>
        /// <returns></returns>
        public ExecutionResult RunAsJavaPassThrough(StackFrame callingFrame, Type service, params object[] list)
        {
            var retval = ExecutionResult.Empty;
            var result = ExecutionResult.Empty;
            KeyValuePair <JniMethodDescription, Tuple <IEntity, IEntity, IEntity> >?found = null;
            var exceptions = new StringBuilder(Win32Helper.Max_BufferSizeForMessagesFromJni);

            var returnValueGetter = ReturnDelegateBasedOnType(retval);

            try {
                if (IsJvmLoaded.Value)
                {
                    _perfCounters.IncrementCounter(Enums.PerfCounter.TotalRequests);                     // Increase "TotalRequest" performance counter
                    var methodKey = new JniMethodDescription(callingFrame, service);
                    // Let's retrieve method metadata from dictionary (if exists), otherwise we'll get it from database
                    if (CachedJniMethods.ContainsKey(methodKey.MethodSignature))
                    {
                        found = CachedJniMethods[methodKey.MethodSignature];
                        _perfCounters.IncrementCounter(Enums.PerfCounter.CachedJniMethodCall);                         // Increase "CachedJniMethodCall"	performance counter
                    }
                    else
                    {
                        result = _dataservice.GetMethodInformationForJniCall(service, callingFrame, list);
                        _perfCounters.IncrementCounter(Enums.PerfCounter.DbJniMethodCall);                         // Increase "DbJniMethodCall"	performance counter
                        var metadata = result.Tag as Tuple <IEntity, IEntity, IEntity>;

                        if (result.IsSuccess && metadata != null)
                        {
                            found = new KeyValuePair <JniMethodDescription, Tuple <IEntity, IEntity, IEntity> >(methodKey, metadata);
                            CachedJniMethods.Add(methodKey.MethodSignature, found.Value);
                        }
                    }

                    RunAsJavaPassThroughHelper(callingFrame, list, found, retval, methodKey, returnValueGetter, exceptions);
                }
            } catch (Exception e) {
                retval.LastExceptionIfAny = e;
            }

            return(retval);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Builds the proxy assembly helper.
        /// </summary>
        /// <param name="codeFiles">The code files.</param>
        /// <param name="workFolder">The work folder.</param>
        /// <param name="jarInformationFile">The jar information file.</param>
        /// <returns></returns>
        private ExecutionResult BuildProxyAssemblyHelper(Dictionary <string, StringBuilder> codeFiles, string workFolder, string jarInformationFile)
        {
            var             tryAgain = true;
            CompilerResults result;
            var             newFiles     = new List <string>();
            var             retval       = ExecutionResult.Empty;
            var             assemblyName = jarInformationFile.Replace(".xml", ".dll");

            try {
                // If work folder doesn't exist, we'll create it
                if (!Directory.Exists(workFolder))
                {
                    Directory.CreateDirectory(workFolder);
                }

                using (var cp = CodeDomProvider.CreateProvider("CSharp")) {
                    foreach (var i in codeFiles)
                    {
                        var fileName = $@"{workFolder}\{i.Key.Substring(0, i.Key.IndexOf('|'))}.cs";

                        // Let's make sure file doesn't exist
                        if (File.Exists(fileName))
                        {
                            File.Delete(fileName);
                        }

                        File.WriteAllText(fileName, i.Value.ToString());                             // and create the source file
                        newFiles.Add(fileName);
                    }

                    var referenceAssemblies = GetReferenceAssemblies();

                    var cParams = new CompilerParameters(new string[] { "System.Linq.dll", "System.ServiceModel.dll", "System.ServiceModel.Web.dll" })
                    {
                        GenerateExecutable = false,
                        OutputAssembly     = assemblyName,
                        CompilerOptions    = "/platform:x64"
                    };

                    // Should we load reference assemblies into AppDomain or not?
                    var loadedAlready = Assembly.GetExecutingAssembly().Modules.Any(p => p.Name.Contains("Simplicity.dotNet."));

                    referenceAssemblies.ForEach(_ => {
                        cParams.ReferencedAssemblies.Add(_);

                        if (!loadedAlready)                         // If reference assemblies hasn't been loaded, we'll load them
                        {
                            Assembly.Load(AssemblyName.GetAssemblyName(_));
                        }
                    });


                    // We'll compile those files that were parsed Ok
                    do
                    {
                        result = cp.CompileAssemblyFromFile(cParams, newFiles.ToArray());

                        if (result.Errors.Count == 0)
                        {
                            tryAgain = false;
                        }
                        else
                        {
                            var errors         = result.Errors.Cast <CompilerError>();
                            var filesToExclude = newFiles.Where(p => !errors.Any(p2 => string.Equals(p, p2.FileName, StringComparison.OrdinalIgnoreCase)));
                            newFiles = filesToExclude.ToList();
                        }
                    } while (tryAgain);

                    // Any errors at compilation?
                    if (result.Errors.Count > 0)
                    {
                        retval.Tag = result.Errors;
                    }
                    else
                    {
                        result.TempFiles.KeepFiles = false;
                        _perfCounters.IncrementCounter(Enums.PerfCounter.ProxyGeneration);                          // Increase "ProxyGeneration" performance counter
                        retval = PerformCleanUp(newFiles, jarInformationFile, result.PathToAssembly, result.TempFiles.Delete);
                    }
                }
            } catch (Exception e) {
                retval.LastExceptionIfAny = e;
            }

            return(retval);
        }