WaitForPipeDrain() public method

public WaitForPipeDrain ( ) : void
return void
Beispiel #1
0
        public Echo(Options options)
        {
            log.Info("creating echo host");

            log.DebugFormat("create interprocess input pipe (handle={0})", options.pipeIn);
            pipeIn = new AnonymousPipeClientStream(PipeDirection.In, options.pipeIn);
            pipeReader = new StreamReader(pipeIn);

            log.DebugFormat("create interprocess output pipe (handle={0})", options.pipeOut);
            pipeOut = new AnonymousPipeClientStream(PipeDirection.Out, options.pipeOut);
            pipeWriter = new StreamWriter(pipeOut);

            log.Debug("create native messaging port");
            port = new Port(pipeIn, pipeOut);

            log.Debug("create stop event");
            stop = new ManualResetEvent(false);

            log.Debug("synchronize processes");
            string sync = pipeReader.ReadLine();
            log.DebugFormat("sent {0}", sync);
            pipeWriter.WriteLine(sync);
            pipeWriter.Flush();
            log.DebugFormat("received {0}", sync);
            pipeOut.WaitForPipeDrain();

            log.Info("created echo host");
        }
Beispiel #2
0
        /// <summary>
        /// Überträgt ein Objekt in eine Kommunikationseinheit.
        /// </summary>
        /// <param name="pipe">Die Kommunikationseinheit.</param>
        /// <param name="serializer">Die Serialisierungsinstanz.</param>
        /// <param name="instance">Das betroffene Objekt.</param>
        internal static void SendToPipe( PipeStream pipe, XmlSerializer serializer, object instance )
        {
            // Create helper
            using (var temp = new MemoryStream())
            {
                // Create writer configuration
                var settings = new XmlWriterSettings { CheckCharacters = false };

                // Create
                using (var writer = XmlWriter.Create( temp, settings ))
                    serializer.Serialize( writer, instance );

                // Read data and create buffer for length
                var len = new byte[sizeof( long )];
                var data = temp.ToArray();

                // Lock briefly
                var lenLock = GCHandle.Alloc( len, GCHandleType.Pinned );
                try
                {
                    // Fill
                    Marshal.WriteInt64( lenLock.AddrOfPinnedObject(), data.LongLength );
                }
                finally
                {
                    // Release
                    lenLock.Free();
                }

                // Send all
                pipe.Write( len, 0, len.Length );

                // Write in blocks
                for (int n = 0; n < data.Length; )
                {
                    // Block size
                    int block = Math.Min( BlockSize, data.Length - n );

                    // Send chunck
                    pipe.Write( data, n, block );
                    pipe.Flush();

                    // Advance
                    n += block;
                }

                // Flush
                pipe.Flush();
                pipe.WaitForPipeDrain();
            }
        }
Beispiel #3
0
        protected void HandlePipeConnection(PipeStream pipeStream, IDictionary<string, object> initialMessage)
        {
            // You think we'd scope these with using() right? They are IDisposable
            //  after all... but nope, the implementation of these is such that
            //  disposing of them also disposes the underlying stream.  Leaving us
            //  with a double (or triple if we close the pipeServer stream ourselves)
            //  close.  Yay.  Instead we abandoned these to the GC knowing that they
            //  are only wrappers anyway and have/use little/no resources of their own.
            BinaryReader reader = new BinaryReader(pipeStream, Encoding.Unicode);
            BinaryWriter writer = new BinaryWriter(pipeStream, Encoding.Unicode);

            try
            {
                // If we should announce with a specific message, do so
                if (initialMessage != null)
                {
                    WriteMessage(writer, initialMessage);
                }

                // So long as our Func<> returns true, we keep going.  When it returns false,
                //  it is done and its time to closeup and look for another client.
                while (StreamAction(reader, writer)) { }
            }
            catch(Exception e)
            {
                LibraryLogging.Error("Error while using pipe connection: {0}", e);
            }

            try
            {
                pipeStream.Flush();
                pipeStream.WaitForPipeDrain();
                pipeStream.Close();
            }
            catch(Exception e)
            {
                LibraryLogging.Error("Error while flushing/closing pipe connection: {0}", e);
            }
        }
        //MAIN
        private NKRemotingProxy(string ns, string id, int nativeSeqMax, NKScriptMessage message, NKScriptContext context, CancellationToken cancelToken)
        {
            this.context = context;
            this._localHandlers = null;
            this.ns = ns;

            this.cancelToken = cancelToken;
            
            var exe = System.Reflection.Assembly.GetEntryAssembly().Location;
            var path = System.IO.Path.GetDirectoryName(exe);
            ProcessStartInfo startInfo = Process.GetCurrentProcess().StartInfo;
            startInfo.FileName = exe;
            startInfo.WorkingDirectory = path;
            startInfo.UseShellExecute = false;
         
            var syncPipeOut = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.Inheritable);
            var syncPipeIn = new AnonymousPipeServerStream(PipeDirection.In, HandleInheritability.Inheritable);
            var pipeOutHandle = syncPipeOut.GetClientHandleAsString();
            var pipeInHandle = syncPipeIn.GetClientHandleAsString();

            this.syncPipeOut = syncPipeOut;
            this.syncPipeIn = syncPipeIn;
            
            startInfo.Arguments = "NKR=" + buildInitMessage(pipeOutHandle, pipeInHandle);

            this.id = id;
            process = Process.Start(startInfo);
            NKEventEmitter.global.emit<string>("NKS.ProcessAdded", id, false);
            process.EnableRaisingEvents = true;
            process.Exited += Process_Exited;
       
            var pipeName = Convert.ToBase64String(getUniqueKey());
            var asyncPipe = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous | PipeOptions.WriteThrough);
            this.asyncPipe = asyncPipe;
            NKScriptChannel.nativeFirstSequence -= 5;

            string nativeFirstSeq = NKScriptChannel.nativeFirstSequence.ToString();
   
            var handshake = new NKRemotingMessage();
            handshake.command = NKRemotingMessage.Command.NKRemotingHandshake;
            handshake.args = new string[] { pipeName, ns, id, nativeSeqMax.ToString() };

            syncPipeOut.WriteByte(100);
            syncPipeOut.Flush();
            syncPipeOut.WaitForPipeDrain();
            syncPipeOut.DisposeLocalCopyOfClientHandle();
            syncPipeIn.DisposeLocalCopyOfClientHandle();

            writeObject(syncPipeOut, handshake);
            syncPipeOut.WaitForPipeDrain();

            var handshakeReply = readObject(syncPipeIn);
            if (handshakeReply == null || handshakeReply.command != NKRemotingMessage.Command.NKRemotingHandshake)
                Environment.Exit(911);

            asyncPipe.WaitForConnection();
            cancelToken.Register(requestClientTeardown);
            var nkready = readObject(asyncPipe);
            if (nkready == null || nkready.command != NKRemotingMessage.Command.NKRemotingReady)
               Environment.Exit(910);
     
            Task.Factory.StartNew((s)=> _processServerMessages(asyncPipe), null, cancelToken, TaskCreationOptions.LongRunning, TaskScheduler.Default);
            NKEventEmitter.global.forward<NKEvent>(eventForwarderFromMain);

        }