public static string GetNetworkPath(string host)
        {
#if VARIABLE_NETWORK_PATHS
            System.Net.Sockets.Socket servSock = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
            servSock.Connect(host, 55900);
            System.Net.Sockets.NetworkStream servStm = new XNetworkStream(servSock);

            string netpath = GetNetworkPath(servStm, host);

            servSock.Close();
            servStm.Close();

            return(netpath);
#else
            return(LocalPathToNetworkPath(_netpath, host));
#endif
        }
        // args: <ipaddr> <portnum> <typechar> <capacity> <logfile> <jid>
        static void Main(string[] args)
        {
            MySpace.DataMining.AELight.Surrogate.LogonMachines();

            try
            {

#if DEBUGnoisy
                XLog.errorlog("DistributedObjectsSlave EntryPoint: " + Environment.CommandLine);
#endif

#if DEBUG
                //System.Threading.Thread.Sleep(1000 * 8);
                {
                    //string computer_name = System.Environment.GetEnvironmentVariable("COMPUTERNAME");
                    //if (computer_name == "MAPDDRULE" || computer_name == "MAPDCMILLER")
                    {
                        if (System.IO.File.Exists("sleep.txt"))
                        {
                            System.Threading.Thread.Sleep(1000 * 8);
                            int i32 = 1 + 32;
                        }
                    }
                }
#endif

#if DEBUG
                SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);
#endif

                XLog.UserLogFile = args[4];
                if (XLog.UserLogFile.StartsWith("&"))
                {
                    XLog.UserLogFile = XLog.UserLogFile.Substring(1);
                    XLog.DelimitUserErrors = true;
                }

#if SLAVE_TRACE
                try
                {
                    Thread mainthread = System.Threading.Thread.CurrentThread;
                    System.Threading.Thread stthd = new System.Threading.Thread(
                        new System.Threading.ThreadStart(
                        delegate
                        {
                            string spid = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
                            try
                            {
                                string dotracefile = spid + ".trace";
                                const string tracefiledelim = "{C8683F6C-0655-42e7-ACD9-0DDED6509A7C}";
                                for (; ; )
                                {
                                    System.IO.StreamWriter traceout = null;
                                    for (System.Threading.Thread.Sleep(1000 * 60)
                                        ; !System.IO.File.Exists(dotracefile)
                                        ; System.Threading.Thread.Sleep(1000 * 60))
                                    {
                                    }
                                    {
                                        string[] tfc;
                                        try
                                        {
                                            tfc = System.IO.File.ReadAllLines(dotracefile);
                                        }
                                        catch
                                        {
                                            continue;
                                        }
                                        if (tfc.Length < 1 || "." != tfc[tfc.Length - 1])
                                        {
                                            continue;
                                        }
                                        try
                                        {
                                            System.IO.File.Delete(dotracefile);
                                        }
                                        catch
                                        {
                                            continue;
                                        }
                                        if ("." != tfc[0])
                                        {
                                            string traceoutfp = tfc[0];
                                            try
                                            {
                                                traceout = System.IO.File.CreateText(traceoutfp);
                                                traceout.Write("BEGIN:");
                                                traceout.WriteLine(tracefiledelim);
                                            }
                                            catch
                                            {
                                                continue;
                                            }
                                        }
                                    }
                                    if (null == traceout)
                                    {
                                        XLog.log("SLAVE_TRACE: " + spid + " Start");
                                    }
                                    for (; ; System.Threading.Thread.Sleep(1000 * 60))
                                    {
                                        {
                                            try
                                            {
#if SLAVE_TRACE_PORT
                                                if (null == traceout)
                                                {
                                                    try
                                                    {
                                                        StringBuilder sbtp = new StringBuilder();
                                                        sbtp.Append("SLAVE_TRACE_PORT: " + spid + ":");
                                                        for (int i = 0; i < DOSlave_TracePorts.Count; i++)
                                                        {
                                                            sbtp.Append(' ');
                                                            sbtp.Append(DOSlave_TracePorts[i]);
                                                        }
                                                        if (0 == DOSlave_TracePorts.Count)
                                                        {
                                                            sbtp.Append(" None");
                                                        }
                                                        XLog.log(sbtp.ToString());
                                                    }
                                                    catch
                                                    {
                                                    }
                                                }
#endif
                                                bool thdsuspended = false;
                                                try
                                                {
                                                    mainthread.Suspend();
                                                    thdsuspended = true;
                                                }
                                                catch (System.Threading.ThreadStateException)
                                                {
                                                }
                                                try
                                                {
                                                    System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace(mainthread, false);
                                                    StringBuilder sbst = new StringBuilder();
                                                    const int maxframesprint = 15;
                                                    for (int i = 0, imax = Math.Min(maxframesprint, st.FrameCount); i < imax; i++)
                                                    {
                                                        if (0 != sbst.Length)
                                                        {
                                                            sbst.Append(", ");
                                                        }
                                                        string mn = "N/A";
                                                        try
                                                        {
                                                            System.Reflection.MethodBase mb = st.GetFrame(i).GetMethod();
                                                            mn = mb.ReflectedType.Name + "." + mb.Name;
                                                        }
                                                        catch
                                                        {
                                                        }
                                                        sbst.Append(mn);
                                                    }
                                                    if (st.FrameCount > maxframesprint)
                                                    {
                                                        sbst.Append(" ... ");
                                                        sbst.Append(st.FrameCount - maxframesprint);
                                                        sbst.Append(" more");
                                                    }
                                                    if (null == traceout)
                                                    {
                                                        XLog.log("SLAVE_TRACE: " + spid + " Trace: " + sbst.ToString());
                                                    }
                                                    else
                                                    {
                                                        traceout.WriteLine(sbst.ToString());
                                                    }
                                                }
                                                catch (Exception e)
                                                {
                                                    XLog.log("SLAVE_TRACE: " + spid + " Error: " + e.ToString());
                                                }
                                                finally
                                                {
                                                    if (thdsuspended)
                                                    {
                                                        mainthread.Resume();
                                                    }
                                                }
                                            }
                                            catch (Exception e)
                                            {
                                                XLog.log("SLAVE_TRACE: " + spid + " " + mainthread.Name + " Trace Error: Cannot access thread: " + e.ToString());
                                            }
                                        }

                                        if (null != traceout)
                                        {
                                            traceout.Write(tracefiledelim);
                                            traceout.WriteLine(":END");
                                            traceout.Close();
                                            break;
                                        }
                                    }

                                }
                            }
                            catch (Exception e)
                            {
                                XLog.log("SLAVE_TRACE: " + spid + " Trace Failure: " + e.Message);
                            }
                        }));
                    stthd.IsBackground = true;
                    stthd.Start();
                }
                catch (Exception est)
                {
                    XLog.log("SLAVE_TRACE: Thread start error: " + est.ToString());
                }
#endif

                sjid = args[5];
                {
                    int ic = sjid.IndexOf(':');
                    if (-1 != ic)
                    {
                        jobdesc = Encoding.UTF8.GetString(Convert.FromBase64String(sjid.Substring(ic + 1)));
                        sjid = sjid.Substring(0, ic);
                    }
                }
                jid = long.Parse(sjid);

                try
                {
                    Environment.SetEnvironmentVariable("DOSLAVE", "DO5");
                }
                catch
                {
                }

                System.Xml.XmlDocument xd = new System.Xml.XmlDocument();
#if DEBUGslaveconfigload
                Random _scsr = new Random(DateTime.Now.Millisecond / 2 + System.Threading.Thread.CurrentThread.ManagedThreadId / 2);
                //for (int i = 0; i < 50; i++)
                {
                    System.Threading.Thread.Sleep(_scsr.Next(50, 200));
                    try
                    {
                        xd.Load("slaveconfig.j" + sjid + ".xml");
                        InitXmlConfig(xd);
                    }
                    catch (System.IO.FileNotFoundException e)
                    {
                        //System.Diagnostics.Debugger.Launch();
                    }
                    catch (Exception e)
                    {
                        System.Diagnostics.Debugger.Launch();
                        throw;
                    }
                }
#else
                try
                {
                    xd.Load("slaveconfig.j" + sjid + ".xml");
                    InitXmlConfig(xd);
                }
                catch (System.IO.FileNotFoundException e)
                {
                }
#endif

                if (XLog.logging)
                {
                    XLog.log("New Sub Process: '" + args[0] + "' '" + args[1] + "' '" + args[2] + "' '" + args[3] + "' '" + args[4] + "' '" + args[5] + "'");
                }

                Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
                string host = args[0];
                int portnum = ushort.Parse(args[1]);
#if SLAVE_TRACE_PORT
                DOSlave_TracePorts.Add(portnum);
#endif
                char typechar = args[2][0];
                try
                {
                    Thread.Sleep(100); // Give DLL a chance to start accepting.
                    sock.Connect(host, portnum);
                }
                catch (Exception e)
                {
                    throw new Exception("Sub-process-to-client(dll) connection error: " + e.ToString() + "  [Note: ensure port " + portnum.ToString() + " is free / not blocked]");
                }
                IDistObject dop;
                if ('H' == typechar)
                {
                    int capacity = ParseCapacity(args[3]);
                    if (XLog.logging)
                    {
                        XLog.log("Connected; creating Hashtable with capacity " + args[3]);
                    }
                    dop = HashtableObjectPart.Create(capacity);
                }
                else if ('8' == typechar)
                {
                    int capacity = ParseCapacity(args[3]);
                    if (XLog.logging)
                    {
                        XLog.log("Connected; creating IntComboList with capacity " + args[3]);
                    }
                    dop = IntComboListPart.Create(capacity);
                }
                else if ('C' == typechar) // 12 hex
                {
                    int capacity = ParseCapacity(args[3]);
                    if (XLog.logging)
                    {
                        XLog.log("Connected; creating LongIntComboList with capacity " + args[3]);
                    }
                    dop = LongIntComboListPart.Create(capacity);
                }
                else if ('A' == typechar)
                {
                    //int capacity = ParseCapacity(args[3]);
                    string[] a = args[3].Split(';');
                    int count_capacity = ParseCapacity(a[0]);
                    int estimated_row_capacity = ParseCapacity(a[1]);
                    int keylen = int.Parse(a[2]);
                    if (XLog.logging)
                    {
                        XLog.log("Connected; creating ArrayComboList(keylength=" + keylen.ToString() + ") with capacity " + args[3]);
                    }
                    dop = ArrayComboListPart.Create(count_capacity, estimated_row_capacity, keylen);
                }
                else if ('R' == typechar)
                {
                    if (XLog.logging)
                    {
                        XLog.log("Connected; creating Remote");
                    }
                    dop = RemotePart.Create();
                }
                else if ('F' == typechar)
                {
                    //int capacity = ParseCapacity(args[3]);
                    string[] a = args[3].Split(';');
                    int keylen = ParseCapacity(a[2]);
                    int valuelen = ParseCapacity(a[3]);
                    if (XLog.logging)
                    {
                        XLog.log("Connected; creating FixedArrayComboList(keylength=" + keylen.ToString() + ";valuelength=" + valuelen.ToString() + ")");
                    }
                    dop = FixedArrayComboListPart.Create(keylen, valuelen);
                }
                else
                {
                    throw new Exception("Data type not supported");
                }

                NetworkStream nstm = new XNetworkStream(sock);
                {
                    // New handshake with client(dll)...
                    nstm.WriteByte(1);
                    // ... and the SlavePID:
                    int SlavePID = System.Diagnostics.Process.GetCurrentProcess().Id;
                    byte[] bpid = DistObjectBase.ToBytes(SlavePID);
                    XContent.SendXContent(nstm, bpid);
                }

                {
                    int pid = System.Diagnostics.Process.GetCurrentProcess().Id;
                    string spid = pid.ToString();
                    string pidfilename = spid + ".j" + sjid + ".slave.pid";
                    StreamWriter pidfile = new StreamWriter(pidfilename);
                    pidfile.WriteLine(pid);
                    pidfile.WriteLine(System.DateTime.Now);
                    pidfile.WriteLine("jid={0}", sjid);
                    pidfile.Flush();
                    for (; ; )
                    {
                        try
                        {
                            dop.ProcessCommands(nstm);
                            break;
                        }
                        catch (DistObjectAbortException e)
                        {
                            XLog.errorlog("ProcessCommands exception: " + e.ToString() + " ((DistObjectAbortException))");
                            break; // !
                        }
                        catch (Exception e)
                        {
                            XLog.errorlog("ProcessCommands exception: " + e.ToString() + " ((recovering from this exception))");
                        }
                    }
                    pidfile.Close();
                    try
                    {
                        System.IO.File.Delete(pidfilename);
                    }
                    catch
                    {
                    }
                }
            }
            catch (Exception e)
            {
                XLog.errorlog("Main exception: " + e.ToString());
            }
        }
        public static string GetNetworkPath(string host)
        {
#if VARIABLE_NETWORK_PATHS
            System.Net.Sockets.Socket servSock = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
            servSock.Connect(host, 55900);
            System.Net.Sockets.NetworkStream servStm = new XNetworkStream(servSock);

            string netpath = GetNetworkPath(servStm, host);

            servSock.Close();
            servStm.Close();

            return netpath;
#else
            return LocalPathToNetworkPath(_netpath, host);
#endif
        }
        public virtual void Open()
        {
            if (didopen)
            {
                throw new Exception("Attempted to Open after already Open");
            }
            didopen = true;
            string portfilename = null;
            System.IO.FileStream portfile = null;
            try
            {
                Socket lsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPEndPoint lipep;
                //int lptests = 0;
                for (; ; )
                {
                    // Try a few ports...
                    lipep = new IPEndPoint(IPAddress.Any, GetSlavePort());
                    try
                    {
                        System.Threading.Mutex lm = new System.Threading.Mutex(false, "DODLL_Listen{2FDD7284-14A8-4f4d-8448-0CE229C1E596}");
                        lm.WaitOne();
                        try
                        {
                            string spf = lipep.Port.ToString() + ".pf";
                            if (System.IO.File.Exists(spf))
                            {
                                continue;
                            }
                            lsock.Bind(lipep);
                            lsock.Listen(2);
                            portfile = new System.IO.FileStream(spf, System.IO.FileMode.Create, System.IO.FileAccess.Write,
                                System.IO.FileShare.Delete, 8, System.IO.FileOptions.DeleteOnClose);
                            portfilename = spf;
                        }
                        finally
                        {
                            lm.ReleaseMutex();
                        }
                    }
                    catch (SocketException e)
                    {
                        //if (++lptests < 4)
                        {
                            continue;
                        }
                        //throw new Exception(e.ToString() + "  [Note: ensure port " + lipep.Port.ToString() + " is free / not blocked (ports >= " + SlavePortMin.ToString() + ")]");
                    }
                    break;
                }
#if DEBUG
                this.OpenPort = lipep.Port;
                lock (AllOpenPorts)
                {
                    AllOpenPorts.Add(this.OpenPort);
                }
#endif

                foreach (SlaveInfo slave in dslaves)
                {
                    NetworkStream servStm = null;

#if DEBUGfailtest
                    bool failtest = true;
#else
                    const bool failtest = false;
#endif
                    for (; ; )
                    {
                        Socket servSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        servSock.Connect(slave.blockinfo[3], 55900);

                        servStm = new XNetworkStream(servSock);

                        servStm.WriteByte((byte)'B'); // AddBlock.
                        XContent.SendXContent(servStm, slave.sblockinfo);
                        XContent.SendXContent(servStm, lipep.Port.ToString());
                        XContent.SendXContent(servStm, sjid + ":" + Convert.ToBase64String(Encoding.UTF8.GetBytes(jobdesc)));
                        {
                            int rB = servStm.ReadByte();
                            if ('+' != rB)
                            {
                                if ('_' == rB)
                                {
                                    throw new Exception("Error returned from AddBlock: " + XContent.ReceiveXString(servStm, null));
                                }
                                else
                                {
                                    throw new Exception("AddBlock failure");
                                }
                            }
                        }

                        // 30000000 microseconds == 30 seconds
                        if (failtest || !lsock.Poll(30000000, SelectMode.SelectRead))
                        {
#if DEBUGfailtest
                            failtest = false;
#endif
                            servStm.Close();
                            continue;
                        }
                        Socket slaveSock = lsock.Accept();
                        slave.nstm = new XNetworkStream(slaveSock);
                        break;
                    }
                    if (1 != slave.nstm.ReadByte())
                    {
                        throw new Exception("Sub process connection error: invalid handshake  [Non-sub-process connection?]");
                    }
                    {
                        int len;
                        byte[] bpid = XContent.ReceiveXBytes(slave.nstm, out len, null);
                        if (len < 4)
                        {
                            throw new Exception("Sub process connection error: invalid SlavePID handshake");
                        }
                        slave.pid = BytesToInt(bpid);
                    }

                    servStm.WriteByte((byte)'\\');
                    servStm.Close(1000);
                }

                lsock.Close();
            }
            catch (FormatException e)
            {
                throw new FormatException("Format error in Open: " + e.ToString());
            }
            catch (Exception e)
            {
                throw new Exception("Error in Open: " + e.ToString() + "  [Note: ensure the Windows service is running]");
            }
            finally
            {
#if DEBUG
                if (0 != this.OpenPort)
                {
                    lock (AllOpenPorts)
                    {
                        AllOpenPorts.Remove(this.OpenPort);
                    }
                }
#endif
                if (null != portfile)
                {
                    System.Threading.Mutex lm = new System.Threading.Mutex(false, "DODLL_Listen{2FDD7284-14A8-4f4d-8448-0CE229C1E596}");
                    lm.WaitOne();
                    try
                    {
                        if (null != portfile)
                        {
                            portfile.Close();
                        }
                        System.IO.File.Delete(portfilename);
                    }
                    catch
                    {
                    }
                    finally
                    {
                        lm.ReleaseMutex();
                    }
                }
            }
        }
Exemple #5
0
        // args: <ipaddr> <portnum> <typechar> <capacity> <logfile> <jid>
        static void Main(string[] args)
        {
            MySpace.DataMining.AELight.Surrogate.LogonMachines();

            try
            {
#if DEBUGnoisy
                XLog.errorlog("DistributedObjectsSlave EntryPoint: " + Environment.CommandLine);
#endif

#if DEBUG
                //System.Threading.Thread.Sleep(1000 * 8);
                {
                    //string computer_name = System.Environment.GetEnvironmentVariable("COMPUTERNAME");
                    //if (computer_name == "MAPDDRULE" || computer_name == "MAPDCMILLER")
                    {
                        if (System.IO.File.Exists("sleep.txt"))
                        {
                            System.Threading.Thread.Sleep(1000 * 8);
                            int i32 = 1 + 32;
                        }
                    }
                }
#endif

#if DEBUG
                SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);
#endif

                XLog.UserLogFile = args[4];
                if (XLog.UserLogFile.StartsWith("&"))
                {
                    XLog.UserLogFile       = XLog.UserLogFile.Substring(1);
                    XLog.DelimitUserErrors = true;
                }

#if SLAVE_TRACE
                try
                {
                    Thread mainthread             = System.Threading.Thread.CurrentThread;
                    System.Threading.Thread stthd = new System.Threading.Thread(
                        new System.Threading.ThreadStart(
                            delegate
                    {
                        string spid = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
                        try
                        {
                            string dotracefile          = spid + ".trace";
                            const string tracefiledelim = "{C8683F6C-0655-42e7-ACD9-0DDED6509A7C}";
                            for (; ;)
                            {
                                System.IO.StreamWriter traceout = null;
                                for (System.Threading.Thread.Sleep(1000 * 60)
                                     ; !System.IO.File.Exists(dotracefile)
                                     ; System.Threading.Thread.Sleep(1000 * 60))
                                {
                                }
                                {
                                    string[] tfc;
                                    try
                                    {
                                        tfc = System.IO.File.ReadAllLines(dotracefile);
                                    }
                                    catch
                                    {
                                        continue;
                                    }
                                    if (tfc.Length < 1 || "." != tfc[tfc.Length - 1])
                                    {
                                        continue;
                                    }
                                    try
                                    {
                                        System.IO.File.Delete(dotracefile);
                                    }
                                    catch
                                    {
                                        continue;
                                    }
                                    if ("." != tfc[0])
                                    {
                                        string traceoutfp = tfc[0];
                                        try
                                        {
                                            traceout = System.IO.File.CreateText(traceoutfp);
                                            traceout.Write("BEGIN:");
                                            traceout.WriteLine(tracefiledelim);
                                        }
                                        catch
                                        {
                                            continue;
                                        }
                                    }
                                }
                                if (null == traceout)
                                {
                                    XLog.log("SLAVE_TRACE: " + spid + " Start");
                                }
                                for (; ; System.Threading.Thread.Sleep(1000 * 60))
                                {
                                    {
                                        try
                                        {
#if SLAVE_TRACE_PORT
                                            if (null == traceout)
                                            {
                                                try
                                                {
                                                    StringBuilder sbtp = new StringBuilder();
                                                    sbtp.Append("SLAVE_TRACE_PORT: " + spid + ":");
                                                    for (int i = 0; i < DOSlave_TracePorts.Count; i++)
                                                    {
                                                        sbtp.Append(' ');
                                                        sbtp.Append(DOSlave_TracePorts[i]);
                                                    }
                                                    if (0 == DOSlave_TracePorts.Count)
                                                    {
                                                        sbtp.Append(" None");
                                                    }
                                                    XLog.log(sbtp.ToString());
                                                }
                                                catch
                                                {
                                                }
                                            }
#endif
                                            bool thdsuspended = false;
                                            try
                                            {
                                                mainthread.Suspend();
                                                thdsuspended = true;
                                            }
                                            catch (System.Threading.ThreadStateException)
                                            {
                                            }
                                            try
                                            {
                                                System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace(mainthread, false);
                                                StringBuilder sbst       = new StringBuilder();
                                                const int maxframesprint = 15;
                                                for (int i = 0, imax = Math.Min(maxframesprint, st.FrameCount); i < imax; i++)
                                                {
                                                    if (0 != sbst.Length)
                                                    {
                                                        sbst.Append(", ");
                                                    }
                                                    string mn = "N/A";
                                                    try
                                                    {
                                                        System.Reflection.MethodBase mb = st.GetFrame(i).GetMethod();
                                                        mn = mb.ReflectedType.Name + "." + mb.Name;
                                                    }
                                                    catch
                                                    {
                                                    }
                                                    sbst.Append(mn);
                                                }
                                                if (st.FrameCount > maxframesprint)
                                                {
                                                    sbst.Append(" ... ");
                                                    sbst.Append(st.FrameCount - maxframesprint);
                                                    sbst.Append(" more");
                                                }
                                                if (null == traceout)
                                                {
                                                    XLog.log("SLAVE_TRACE: " + spid + " Trace: " + sbst.ToString());
                                                }
                                                else
                                                {
                                                    traceout.WriteLine(sbst.ToString());
                                                }
                                            }
                                            catch (Exception e)
                                            {
                                                XLog.log("SLAVE_TRACE: " + spid + " Error: " + e.ToString());
                                            }
                                            finally
                                            {
                                                if (thdsuspended)
                                                {
                                                    mainthread.Resume();
                                                }
                                            }
                                        }
                                        catch (Exception e)
                                        {
                                            XLog.log("SLAVE_TRACE: " + spid + " " + mainthread.Name + " Trace Error: Cannot access thread: " + e.ToString());
                                        }
                                    }

                                    if (null != traceout)
                                    {
                                        traceout.Write(tracefiledelim);
                                        traceout.WriteLine(":END");
                                        traceout.Close();
                                        break;
                                    }
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            XLog.log("SLAVE_TRACE: " + spid + " Trace Failure: " + e.Message);
                        }
                    }));
                    stthd.IsBackground = true;
                    stthd.Start();
                }
                catch (Exception est)
                {
                    XLog.log("SLAVE_TRACE: Thread start error: " + est.ToString());
                }
#endif

                sjid = args[5];
                {
                    int ic = sjid.IndexOf(':');
                    if (-1 != ic)
                    {
                        jobdesc = Encoding.UTF8.GetString(Convert.FromBase64String(sjid.Substring(ic + 1)));
                        sjid    = sjid.Substring(0, ic);
                    }
                }
                jid = long.Parse(sjid);

                try
                {
                    Environment.SetEnvironmentVariable("DOSLAVE", "DO5");
                }
                catch
                {
                }

                System.Xml.XmlDocument xd = new System.Xml.XmlDocument();
#if DEBUGslaveconfigload
                Random _scsr = new Random(DateTime.Now.Millisecond / 2 + System.Threading.Thread.CurrentThread.ManagedThreadId / 2);
                //for (int i = 0; i < 50; i++)
                {
                    System.Threading.Thread.Sleep(_scsr.Next(50, 200));
                    try
                    {
                        xd.Load("slaveconfig.j" + sjid + ".xml");
                        InitXmlConfig(xd);
                    }
                    catch (System.IO.FileNotFoundException e)
                    {
                        //System.Diagnostics.Debugger.Launch();
                    }
                    catch (Exception e)
                    {
                        System.Diagnostics.Debugger.Launch();
                        throw;
                    }
                }
#else
                try
                {
                    xd.Load("slaveconfig.j" + sjid + ".xml");
                    InitXmlConfig(xd);
                }
                catch (System.IO.FileNotFoundException e)
                {
                }
#endif

                if (XLog.logging)
                {
                    XLog.log("New Sub Process: '" + args[0] + "' '" + args[1] + "' '" + args[2] + "' '" + args[3] + "' '" + args[4] + "' '" + args[5] + "'");
                }

                Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
                string host    = args[0];
                int    portnum = ushort.Parse(args[1]);
#if SLAVE_TRACE_PORT
                DOSlave_TracePorts.Add(portnum);
#endif
                char typechar = args[2][0];
                try
                {
                    Thread.Sleep(100); // Give DLL a chance to start accepting.
                    sock.Connect(host, portnum);
                }
                catch (Exception e)
                {
                    throw new Exception("Sub-process-to-client(dll) connection error: " + e.ToString() + "  [Note: ensure port " + portnum.ToString() + " is free / not blocked]");
                }
                IDistObject dop;
                if ('H' == typechar)
                {
                    int capacity = ParseCapacity(args[3]);
                    if (XLog.logging)
                    {
                        XLog.log("Connected; creating Hashtable with capacity " + args[3]);
                    }
                    dop = HashtableObjectPart.Create(capacity);
                }
                else if ('8' == typechar)
                {
                    int capacity = ParseCapacity(args[3]);
                    if (XLog.logging)
                    {
                        XLog.log("Connected; creating IntComboList with capacity " + args[3]);
                    }
                    dop = IntComboListPart.Create(capacity);
                }
                else if ('C' == typechar) // 12 hex
                {
                    int capacity = ParseCapacity(args[3]);
                    if (XLog.logging)
                    {
                        XLog.log("Connected; creating LongIntComboList with capacity " + args[3]);
                    }
                    dop = LongIntComboListPart.Create(capacity);
                }
                else if ('A' == typechar)
                {
                    //int capacity = ParseCapacity(args[3]);
                    string[] a = args[3].Split(';');
                    int      count_capacity         = ParseCapacity(a[0]);
                    int      estimated_row_capacity = ParseCapacity(a[1]);
                    int      keylen = int.Parse(a[2]);
                    if (XLog.logging)
                    {
                        XLog.log("Connected; creating ArrayComboList(keylength=" + keylen.ToString() + ") with capacity " + args[3]);
                    }
                    dop = ArrayComboListPart.Create(count_capacity, estimated_row_capacity, keylen);
                }
                else if ('R' == typechar)
                {
                    if (XLog.logging)
                    {
                        XLog.log("Connected; creating Remote");
                    }
                    dop = RemotePart.Create();
                }
                else if ('F' == typechar)
                {
                    //int capacity = ParseCapacity(args[3]);
                    string[] a        = args[3].Split(';');
                    int      keylen   = ParseCapacity(a[2]);
                    int      valuelen = ParseCapacity(a[3]);
                    if (XLog.logging)
                    {
                        XLog.log("Connected; creating FixedArrayComboList(keylength=" + keylen.ToString() + ";valuelength=" + valuelen.ToString() + ")");
                    }
                    dop = FixedArrayComboListPart.Create(keylen, valuelen);
                }
                else
                {
                    throw new Exception("Data type not supported");
                }

                NetworkStream nstm = new XNetworkStream(sock);
                {
                    // New handshake with client(dll)...
                    nstm.WriteByte(1);
                    // ... and the SlavePID:
                    int    SlavePID = System.Diagnostics.Process.GetCurrentProcess().Id;
                    byte[] bpid     = DistObjectBase.ToBytes(SlavePID);
                    XContent.SendXContent(nstm, bpid);
                }

                {
                    int          pid         = System.Diagnostics.Process.GetCurrentProcess().Id;
                    string       spid        = pid.ToString();
                    string       pidfilename = spid + ".j" + sjid + ".slave.pid";
                    StreamWriter pidfile     = new StreamWriter(pidfilename);
                    pidfile.WriteLine(pid);
                    pidfile.WriteLine(System.DateTime.Now);
                    pidfile.WriteLine("jid={0}", sjid);
                    pidfile.Flush();
                    for (; ;)
                    {
                        try
                        {
                            dop.ProcessCommands(nstm);
                            break;
                        }
                        catch (DistObjectAbortException e)
                        {
                            XLog.errorlog("ProcessCommands exception: " + e.ToString() + " ((DistObjectAbortException))");
                            break; // !
                        }
                        catch (Exception e)
                        {
                            XLog.errorlog("ProcessCommands exception: " + e.ToString() + " ((recovering from this exception))");
                        }
                    }
                    pidfile.Close();
                    try
                    {
                        System.IO.File.Delete(pidfilename);
                    }
                    catch
                    {
                    }
                }
            }
            catch (Exception e)
            {
                XLog.errorlog("Main exception: " + e.ToString());
            }
        }
        public virtual void Open()
        {
            if (didopen)
            {
                throw new Exception("Attempted to Open after already Open");
            }
            didopen = true;
            string portfilename = null;

            System.IO.FileStream portfile = null;
            try
            {
                Socket     lsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPEndPoint lipep;
                //int lptests = 0;
                for (; ;)
                {
                    // Try a few ports...
                    lipep = new IPEndPoint(IPAddress.Any, GetSlavePort());
                    try
                    {
                        System.Threading.Mutex lm = new System.Threading.Mutex(false, "DODLL_Listen{2FDD7284-14A8-4f4d-8448-0CE229C1E596}");
                        lm.WaitOne();
                        try
                        {
                            string spf = lipep.Port.ToString() + ".pf";
                            if (System.IO.File.Exists(spf))
                            {
                                continue;
                            }
                            lsock.Bind(lipep);
                            lsock.Listen(2);
                            portfile = new System.IO.FileStream(spf, System.IO.FileMode.Create, System.IO.FileAccess.Write,
                                                                System.IO.FileShare.Delete, 8, System.IO.FileOptions.DeleteOnClose);
                            portfilename = spf;
                        }
                        finally
                        {
                            lm.ReleaseMutex();
                        }
                    }
                    catch (SocketException e)
                    {
                        //if (++lptests < 4)
                        {
                            continue;
                        }
                        //throw new Exception(e.ToString() + "  [Note: ensure port " + lipep.Port.ToString() + " is free / not blocked (ports >= " + SlavePortMin.ToString() + ")]");
                    }
                    break;
                }
#if DEBUG
                this.OpenPort = lipep.Port;
                lock (AllOpenPorts)
                {
                    AllOpenPorts.Add(this.OpenPort);
                }
#endif

                foreach (SlaveInfo slave in dslaves)
                {
                    NetworkStream servStm = null;

#if DEBUGfailtest
                    bool failtest = true;
#else
                    const bool failtest = false;
#endif
                    for (; ;)
                    {
                        Socket servSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        servSock.Connect(slave.blockinfo[3], 55900);

                        servStm = new XNetworkStream(servSock);

                        servStm.WriteByte((byte)'B'); // AddBlock.
                        XContent.SendXContent(servStm, slave.sblockinfo);
                        XContent.SendXContent(servStm, lipep.Port.ToString());
                        XContent.SendXContent(servStm, sjid + ":" + Convert.ToBase64String(Encoding.UTF8.GetBytes(jobdesc)));
                        {
                            int rB = servStm.ReadByte();
                            if ('+' != rB)
                            {
                                if ('_' == rB)
                                {
                                    throw new Exception("Error returned from AddBlock: " + XContent.ReceiveXString(servStm, null));
                                }
                                else
                                {
                                    throw new Exception("AddBlock failure");
                                }
                            }
                        }

                        // 30000000 microseconds == 30 seconds
                        if (failtest || !lsock.Poll(30000000, SelectMode.SelectRead))
                        {
#if DEBUGfailtest
                            failtest = false;
#endif
                            servStm.Close();
                            continue;
                        }
                        Socket slaveSock = lsock.Accept();
                        slave.nstm = new XNetworkStream(slaveSock);
                        break;
                    }
                    if (1 != slave.nstm.ReadByte())
                    {
                        throw new Exception("Sub process connection error: invalid handshake  [Non-sub-process connection?]");
                    }
                    {
                        int    len;
                        byte[] bpid = XContent.ReceiveXBytes(slave.nstm, out len, null);
                        if (len < 4)
                        {
                            throw new Exception("Sub process connection error: invalid SlavePID handshake");
                        }
                        slave.pid = BytesToInt(bpid);
                    }

                    servStm.WriteByte((byte)'\\');
                    servStm.Close(1000);
                }

                lsock.Close();
            }
            catch (FormatException e)
            {
                throw new FormatException("Format error in Open: " + e.ToString());
            }
            catch (Exception e)
            {
                throw new Exception("Error in Open: " + e.ToString() + "  [Note: ensure the Windows service is running]");
            }
            finally
            {
#if DEBUG
                if (0 != this.OpenPort)
                {
                    lock (AllOpenPorts)
                    {
                        AllOpenPorts.Remove(this.OpenPort);
                    }
                }
#endif
                if (null != portfile)
                {
                    System.Threading.Mutex lm = new System.Threading.Mutex(false, "DODLL_Listen{2FDD7284-14A8-4f4d-8448-0CE229C1E596}");
                    lm.WaitOne();
                    try
                    {
                        if (null != portfile)
                        {
                            portfile.Close();
                        }
                        System.IO.File.Delete(portfilename);
                    }
                    catch
                    {
                    }
                    finally
                    {
                        lm.ReleaseMutex();
                    }
                }
            }
        }