private int ParallelTransfer_Int(IntPtr pServerOfCmd, string cmd, String[] args, uint argCount, IntPtr dictIter, uint threads) { // pServer should be the same as our local one, if not...freak out if (pServerOfCmd != pServer) { return(1); } // we need to fire up threads to run their own operations, forwarding errors back to us // when all of the threads have terminated, we return 0 if no errors, 1 if any exist ParallelTransferArgs transferArgs = new ParallelTransferArgs(); transferArgs.original = this; transferArgs.cmd = cmd; transferArgs.args = args; transferArgs.dict = new List <KeyValuePair>(); // copy the key value pairs out of dictIter, we can't share that StrDictListIterator iter = new StrDictListIterator(this, dictIter); while (iter.NextItem()) { KeyValuePair kv = null; while ((kv = iter.NextEntry()) != null) { transferArgs.dict.Add(kv); } } transferArgs.threads = threads; // initialize the error and server lists parallelErrors = new P4ClientErrorList(null); parallelServers = new List <P4Server>(); List <Thread> threadList = new List <Thread>(); for (uint i = 0; i < threads; i++) { Thread thread = new Thread(P4Server.ParallelTransferThread); thread.Start(transferArgs); threadList.Add(thread); } foreach (Thread t in threadList) { t.Join(); } foreach (P4Server p4Server in parallelServers) { p4Server.Dispose(); } return(parallelErrors.Count == 0 ? 0 : 1); }
/// <summary> /// Thread entry point for running more P4Servers /// </summary> private static void ParallelTransferThread(object args) { ParallelTransferArgs transferArgs = (ParallelTransferArgs)args; // make a new connection to the server and run the command // we should not need trust or fingerprint as this should initiate from a successful (trusted) session using (P4Server target = new P4Server(transferArgs.original)) { // add the server for the original P4Server lock (transferArgs.original.parallelServers) { transferArgs.original.parallelServers.Add(target); } // set the dictionary as protocol settings foreach (KeyValuePair p in transferArgs.dict) { P4Bridge.SetProtocol(target.pServer, p.Key, p.Value); } try { // Note: due to legacy (unused) cmdId code in p4bridge, cmdId < 0 will explicitly not call // the assigned callbacks. set the cmdId from the other's cmdId generator if (target.RunCommand(transferArgs.cmd, transferArgs.original.getCmdId(), true, transferArgs.args, transferArgs.args.Length)) { target.Disconnect(); return; } } catch (P4Exception e) { Debug.Trace(e.Message); } // grab the errors and inject them into the original P4Server P4ClientErrorList list = target.GetErrorResults(0); // sometimes we get here without client errors (e.g. disconnect?) if (transferArgs.original.parallelErrors != null && list != null) { // make sure the threads don't step on each other lock (transferArgs.original.parallelErrors) { foreach (P4ClientError e in list) { transferArgs.original.parallelErrors.Add(e); } } } } }