Merge pull request #11948 from dgquintas/grpclb_fix_rr_shutdown_connectivity

Fix bug in handling of RR connectivity transition to SHUTDOWN
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 90580c5..202af58 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -176,7 +176,7 @@
     ss.header_mappings_dir = '.'
     ss.libraries = 'z'
     ss.dependency "#{s.name}/Interface", version
-    ss.dependency 'BoringSSL', '~> 8.0'
+    ss.dependency 'BoringSSL', '~> 9.0'
     ss.dependency 'nanopb', '~> 0.3'
 
     # To save you from scrolling, this is the last part of the podspec.
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c
index aadba3f..bb9217d 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c
@@ -1769,7 +1769,8 @@
 
   if (!glb_policy->watching_lb_channel) {
     // Watch the LB channel connectivity for connection.
-    glb_policy->lb_channel_connectivity = GRPC_CHANNEL_INIT;
+    glb_policy->lb_channel_connectivity = grpc_channel_check_connectivity_state(
+        glb_policy->lb_channel, true /* try to connect */);
     grpc_channel_element *client_channel_elem = grpc_channel_stack_last_element(
         grpc_channel_get_channel_stack(glb_policy->lb_channel));
     GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter);
diff --git a/src/core/lib/surface/completion_queue.c b/src/core/lib/surface/completion_queue.c
index 978d7b4..3851993 100644
--- a/src/core/lib/surface/completion_queue.c
+++ b/src/core/lib/surface/completion_queue.c
@@ -855,8 +855,7 @@
          inconsistent state. If it is the latter, we shold do a 0-timeout poll
          so that the thread comes back quickly from poll to make a second
          attempt at popping. Not doing this can potentially deadlock this
-         thread
-         forever (if the deadline is infinity) */
+         thread forever (if the deadline is infinity) */
       if (cq_event_queue_num_items(&cqd->queue) > 0) {
         iteration_deadline = gpr_time_0(GPR_CLOCK_MONOTONIC);
       }
@@ -869,10 +868,8 @@
       if (cq_event_queue_num_items(&cqd->queue) > 0) {
         /* Go to the beginning of the loop. No point doing a poll because
            (cq->shutdown == true) is only possible when there is no pending
-           work
-           (i.e cq->pending_events == 0) and any outstanding
-           grpc_cq_completion
-           events are already queued on this cq */
+           work (i.e cq->pending_events == 0) and any outstanding completion
+           events should have already been queued on this cq */
         continue;
       }
 
@@ -909,11 +906,6 @@
     is_finished_arg.first_loop = false;
   }
 
-  GRPC_SURFACE_TRACE_RETURNED_EVENT(cq, &ret);
-  GRPC_CQ_INTERNAL_UNREF(&exec_ctx, cq, "next");
-  grpc_exec_ctx_finish(&exec_ctx);
-  GPR_ASSERT(is_finished_arg.stolen_completion == NULL);
-
   if (cq_event_queue_num_items(&cqd->queue) > 0 &&
       gpr_atm_no_barrier_load(&cqd->pending_events) > 0) {
     gpr_mu_lock(cq->mu);
@@ -921,6 +913,11 @@
     gpr_mu_unlock(cq->mu);
   }
 
+  GRPC_SURFACE_TRACE_RETURNED_EVENT(cq, &ret);
+  GRPC_CQ_INTERNAL_UNREF(&exec_ctx, cq, "next");
+  grpc_exec_ctx_finish(&exec_ctx);
+  GPR_ASSERT(is_finished_arg.stolen_completion == NULL);
+
   GPR_TIMER_END("grpc_completion_queue_next", 0);
 
   return ret;
diff --git a/src/csharp/Grpc.Core.Tests/ThreadingModelTest.cs b/src/csharp/Grpc.Core.Tests/ThreadingModelTest.cs
new file mode 100644
index 0000000..fb18198
--- /dev/null
+++ b/src/csharp/Grpc.Core.Tests/ThreadingModelTest.cs
@@ -0,0 +1,98 @@
+#region Copyright notice and license
+
+// Copyright 2015 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#endregion
+
+using System;
+using NUnit.Framework;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Grpc.Core.Tests
+{
+    public class ThreadingModelTest
+    {
+        const string Host = "127.0.0.1";
+
+        MockServiceHelper helper;
+        Server server;
+        Channel channel;
+
+        [SetUp]
+        public void Init()
+        {
+            helper = new MockServiceHelper(Host);
+            server = helper.GetServer();
+            server.Start();
+            channel = helper.GetChannel();
+        }
+
+        [TearDown]
+        public void Cleanup()
+        {
+            channel.ShutdownAsync().Wait();
+            server.ShutdownAsync().Wait();
+        }
+
+        [Test]
+        public void BlockingCallInServerHandlerDoesNotDeadlock()
+        {
+            helper.UnaryHandler = new UnaryServerMethod<string, string>(async (request, context) =>
+            {
+                int recursionDepth = int.Parse(request);
+                if (recursionDepth <= 0) {
+                    return "SUCCESS";
+                }
+                return Calls.BlockingUnaryCall(helper.CreateUnaryCall(), (recursionDepth - 1).ToString());
+            });
+
+            int maxRecursionDepth = Environment.ProcessorCount * 2;  // make sure we have more pending blocking calls than threads in GrpcThreadPool
+            Assert.AreEqual("SUCCESS", Calls.BlockingUnaryCall(helper.CreateUnaryCall(), maxRecursionDepth.ToString()));
+        }
+
+        [Test]
+        public void HandlerDoesNotRunOnGrpcThread()
+        {
+            helper.UnaryHandler = new UnaryServerMethod<string, string>(async (request, context) =>
+            {
+                if (IsRunningOnGrpcThreadPool()) {
+                    return "Server handler should not run on gRPC threadpool thread.";
+                }
+                return request;
+            });
+
+            Assert.AreEqual("ABC", Calls.BlockingUnaryCall(helper.CreateUnaryCall(), "ABC"));
+        }
+
+        [Test]
+        public async Task ContinuationDoesNotRunOnGrpcThread()
+        {
+            helper.UnaryHandler = new UnaryServerMethod<string, string>(async (request, context) =>
+            {
+                return request;
+            });
+
+            await Calls.AsyncUnaryCall(helper.CreateUnaryCall(), "ABC");
+            Assert.IsFalse(IsRunningOnGrpcThreadPool());
+        }
+
+        private static bool IsRunningOnGrpcThreadPool()
+        {
+            var threadName = Thread.CurrentThread.Name ?? "";
+            return threadName.Contains("grpc");
+        }
+    }
+}
diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj
index 5035829..e32711c 100755
--- a/src/csharp/Grpc.Core/Grpc.Core.csproj
+++ b/src/csharp/Grpc.Core/Grpc.Core.csproj
@@ -64,6 +64,7 @@
   <ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.5' ">
     <PackageReference Include="System.Runtime.Loader" Version="4.0.0" />
     <PackageReference Include="System.Threading.Thread" Version="4.0.0" />
+    <PackageReference Include="System.Threading.ThreadPool" Version="4.0.0" />
   </ItemGroup>
 
   <Import Project="NativeDeps.csproj.include" />
diff --git a/src/csharp/Grpc.Core/GrpcEnvironment.cs b/src/csharp/Grpc.Core/GrpcEnvironment.cs
index 8d0c66a..0663ee9 100644
--- a/src/csharp/Grpc.Core/GrpcEnvironment.cs
+++ b/src/csharp/Grpc.Core/GrpcEnvironment.cs
@@ -39,6 +39,7 @@
         static int refCount;
         static int? customThreadPoolSize;
         static int? customCompletionQueueCount;
+        static bool inlineHandlers;
         static readonly HashSet<Channel> registeredChannels = new HashSet<Channel>();
         static readonly HashSet<Server> registeredServers = new HashSet<Server>();
 
@@ -218,12 +219,31 @@
         }
 
         /// <summary>
+        /// By default, gRPC's internal event handlers get offloaded to .NET default thread pool thread (<c>inlineHandlers=false</c>).
+        /// Setting <c>inlineHandlers</c> to <c>true</c> will allow scheduling the event handlers directly to
+        /// <c>GrpcThreadPool</c> internal threads. That can lead to significant performance gains in some situations,
+        /// but requires user to never block in async code (incorrectly written code can easily lead to deadlocks).
+        /// Inlining handlers is an advanced setting and you should only use it if you know what you are doing.
+        /// Most users should rely on the default value provided by gRPC library.
+        /// Note: this method is part of an experimental API that can change or be removed without any prior notice.
+        /// Note: <c>inlineHandlers=true</c> was the default in gRPC C# v1.4.x and earlier.
+        /// </summary>
+        public static void SetHandlerInlining(bool inlineHandlers)
+        {
+            lock (staticLock)
+            {
+                GrpcPreconditions.CheckState(instance == null, "Can only be set before GrpcEnvironment is initialized");
+                GrpcEnvironment.inlineHandlers = inlineHandlers;
+            }
+        }
+
+        /// <summary>
         /// Creates gRPC environment.
         /// </summary>
         private GrpcEnvironment()
         {
             GrpcNativeInit();
-            threadPool = new GrpcThreadPool(this, GetThreadPoolSizeOrDefault(), GetCompletionQueueCountOrDefault());
+            threadPool = new GrpcThreadPool(this, GetThreadPoolSizeOrDefault(), GetCompletionQueueCountOrDefault(), inlineHandlers);
             threadPool.Start();
         }
 
diff --git a/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs b/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs
index f9ae77c..19b44c2 100644
--- a/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs
+++ b/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs
@@ -33,12 +33,15 @@
     internal class GrpcThreadPool
     {
         static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<GrpcThreadPool>();
+        static readonly WaitCallback RunCompletionQueueEventCallbackSuccess = new WaitCallback((callback) => RunCompletionQueueEventCallback((OpCompletionDelegate) callback, true));
+        static readonly WaitCallback RunCompletionQueueEventCallbackFailure = new WaitCallback((callback) => RunCompletionQueueEventCallback((OpCompletionDelegate) callback, false));
 
         readonly GrpcEnvironment environment;
         readonly object myLock = new object();
         readonly List<Thread> threads = new List<Thread>();
         readonly int poolSize;
         readonly int completionQueueCount;
+        readonly bool inlineHandlers;
 
         readonly List<BasicProfiler> threadProfilers = new List<BasicProfiler>();  // profilers assigned to threadpool threads
 
@@ -52,11 +55,13 @@
         /// <param name="environment">Environment.</param>
         /// <param name="poolSize">Pool size.</param>
         /// <param name="completionQueueCount">Completion queue count.</param>
-        public GrpcThreadPool(GrpcEnvironment environment, int poolSize, int completionQueueCount)
+        /// <param name="inlineHandlers">Handler inlining.</param>
+        public GrpcThreadPool(GrpcEnvironment environment, int poolSize, int completionQueueCount, bool inlineHandlers)
         {
             this.environment = environment;
             this.poolSize = poolSize;
             this.completionQueueCount = completionQueueCount;
+            this.inlineHandlers = inlineHandlers;
             GrpcPreconditions.CheckArgument(poolSize >= completionQueueCount,
                 "Thread pool size cannot be smaller than the number of completion queues used.");
         }
@@ -165,11 +170,19 @@
                     try
                     {
                         var callback = cq.CompletionRegistry.Extract(tag);
-                        callback(success);
+                        // Use cached delegates to avoid unnecessary allocations
+                        if (!inlineHandlers)
+                        {
+                            ThreadPool.QueueUserWorkItem(success ? RunCompletionQueueEventCallbackSuccess : RunCompletionQueueEventCallbackFailure, callback);
+                        }
+                        else
+                        {
+                            RunCompletionQueueEventCallback(callback, success);
+                        }
                     }
                     catch (Exception e)
                     {
-                        Logger.Error(e, "Exception occured while invoking completion delegate");
+                        Logger.Error(e, "Exception occured while extracting event from completion registry.");
                     }
                 }
             }
@@ -186,5 +199,17 @@
             }
             return list.AsReadOnly();
         }
+
+        private static void RunCompletionQueueEventCallback(OpCompletionDelegate callback, bool success)
+        {
+            try
+            {
+                callback(success);
+            }
+            catch (Exception e)
+            {
+                Logger.Error(e, "Exception occured while invoking completion delegate");
+            }
+        }
     }
 }
diff --git a/src/csharp/Grpc.IntegrationTesting/QpsWorker.cs b/src/csharp/Grpc.IntegrationTesting/QpsWorker.cs
index 7009a93..a579fb8 100644
--- a/src/csharp/Grpc.IntegrationTesting/QpsWorker.cs
+++ b/src/csharp/Grpc.IntegrationTesting/QpsWorker.cs
@@ -63,11 +63,6 @@
 
         private async Task RunAsync()
         {
-            // (ThreadPoolSize == ProcessorCount) gives best throughput in benchmarks
-            // and doesn't seem to harm performance even when server and client
-            // are running on the same machine.
-            GrpcEnvironment.SetThreadPoolSize(Environment.ProcessorCount);
-
             string host = "0.0.0.0";
             int port = options.DriverPort;
 
diff --git a/src/csharp/tests.json b/src/csharp/tests.json
index bc6adbb..7841051 100644
--- a/src/csharp/tests.json
+++ b/src/csharp/tests.json
@@ -31,6 +31,7 @@
     "Grpc.Core.Tests.ShutdownHookPendingCallTest",
     "Grpc.Core.Tests.ShutdownHookServerTest",
     "Grpc.Core.Tests.ShutdownTest",
+    "Grpc.Core.Tests.ThreadingModelTest",
     "Grpc.Core.Tests.TimeoutsTest",
     "Grpc.Core.Tests.UserAgentStringTest"
   ],
diff --git "a/src/objective-c/\041ProtoCompiler-gRPCPlugin.podspec" "b/src/objective-c/\041ProtoCompiler-gRPCPlugin.podspec"
index 22527d1..345eecc 100644
--- "a/src/objective-c/\041ProtoCompiler-gRPCPlugin.podspec"
+++ "b/src/objective-c/\041ProtoCompiler-gRPCPlugin.podspec"
@@ -101,7 +101,7 @@
   s.preserve_paths = plugin
 
   # Restrict the protoc version to the one supported by this plugin.
-  s.dependency '!ProtoCompiler', '3.2.0'
+  s.dependency '!ProtoCompiler', '3.3.0'
   # For the Protobuf dependency not to complain:
   s.ios.deployment_target = '7.0'
   s.osx.deployment_target = '10.9'
diff --git "a/src/objective-c/\041ProtoCompiler.podspec" "b/src/objective-c/\041ProtoCompiler.podspec"
index 2e9b944..c3f95f9 100644
--- "a/src/objective-c/\041ProtoCompiler.podspec"
+++ "b/src/objective-c/\041ProtoCompiler.podspec"
@@ -36,7 +36,7 @@
   # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed
   # before them.
   s.name     = '!ProtoCompiler'
-  v = '3.2.0'
+  v = '3.3.0'
   s.version  = v
   s.summary  = 'The Protobuf Compiler (protoc) generates Objective-C files from .proto files'
   s.description = <<-DESC
diff --git a/src/objective-c/BoringSSL.podspec b/src/objective-c/BoringSSL.podspec
index 651bd49..37798ec 100644
--- a/src/objective-c/BoringSSL.podspec
+++ b/src/objective-c/BoringSSL.podspec
@@ -31,7 +31,7 @@
 
 Pod::Spec.new do |s|
   s.name     = 'BoringSSL'
-  version = '8.2'
+  version = '9.0'
   s.version  = version
   s.summary  = 'BoringSSL is a fork of OpenSSL that is designed to meet Google’s needs.'
   # Adapted from the homepage:
@@ -69,9 +69,7 @@
 
   s.source = {
     :git => 'https://boringssl.googlesource.com/boringssl',
-    # Restore this version name hack in the next version!!
-    # :tag => "version_for_cocoapods_#{version}",
-    :tag => "version_for_cocoapods_8.0",
+    :tag => "version_for_cocoapods_#{version}",
   }
 
   name = 'openssl'
@@ -169,7 +167,6 @@
       #include "hkdf.h"
       #include "md4.h"
       #include "md5.h"
-      #include "newhope.h"
       #include "obj_mac.h"
       #include "objects.h"
       #include "opensslv.h"
@@ -183,7 +180,6 @@
       #include "ripemd.h"
       #include "safestack.h"
       #include "srtp.h"
-      #include "time_support.h"
       #include "x509.h"
       #include "x509v3.h"
     EOF
@@ -389,42 +385,42 @@
           0x28340c19,
           0x283480ac,
           0x283500ea,
-          0x2c3228ca,
-          0x2c32a8d8,
-          0x2c3328ea,
-          0x2c33a8fc,
-          0x2c342910,
-          0x2c34a922,
-          0x2c35293d,
-          0x2c35a94f,
-          0x2c362962,
+          0x2c3229b1,
+          0x2c32a9bf,
+          0x2c3329d1,
+          0x2c33a9e3,
+          0x2c3429f7,
+          0x2c34aa09,
+          0x2c352a24,
+          0x2c35aa36,
+          0x2c362a49,
           0x2c36832d,
-          0x2c37296f,
-          0x2c37a981,
-          0x2c382994,
-          0x2c38a9ab,
-          0x2c3929b9,
-          0x2c39a9c9,
-          0x2c3a29db,
-          0x2c3aa9ef,
-          0x2c3b2a00,
-          0x2c3baa1f,
-          0x2c3c2a33,
-          0x2c3caa49,
-          0x2c3d2a62,
-          0x2c3daa7f,
-          0x2c3e2a90,
-          0x2c3eaa9e,
-          0x2c3f2ab6,
-          0x2c3faace,
-          0x2c402adb,
+          0x2c372a56,
+          0x2c37aa68,
+          0x2c382a7b,
+          0x2c38aa92,
+          0x2c392aa0,
+          0x2c39aab0,
+          0x2c3a2ac2,
+          0x2c3aaad6,
+          0x2c3b2ae7,
+          0x2c3bab06,
+          0x2c3c2b1a,
+          0x2c3cab30,
+          0x2c3d2b49,
+          0x2c3dab66,
+          0x2c3e2b77,
+          0x2c3eab85,
+          0x2c3f2b9d,
+          0x2c3fabb5,
+          0x2c402bc2,
           0x2c4090e7,
-          0x2c412aec,
-          0x2c41aaff,
+          0x2c412bd3,
+          0x2c41abe6,
           0x2c4210c0,
-          0x2c42ab10,
+          0x2c42abf7,
           0x2c430720,
-          0x2c43aa11,
+          0x2c43aaf8,
           0x30320000,
           0x30328015,
           0x3033001f,
@@ -577,180 +573,189 @@
           0x403b9861,
           0x403c0064,
           0x403c8083,
-          0x403d18aa,
-          0x403d98c0,
-          0x403e18cf,
-          0x403e98e2,
-          0x403f18fc,
-          0x403f990a,
-          0x4040191f,
-          0x40409933,
-          0x40411950,
-          0x4041996b,
-          0x40421984,
-          0x40429997,
-          0x404319ab,
-          0x404399c3,
-          0x404419da,
+          0x403d18c1,
+          0x403d98d7,
+          0x403e18e6,
+          0x403e98f9,
+          0x403f1913,
+          0x403f9921,
+          0x40401936,
+          0x4040994a,
+          0x40411967,
+          0x40419982,
+          0x4042199b,
+          0x404299ae,
+          0x404319c2,
+          0x404399da,
+          0x404419f1,
           0x404480ac,
-          0x404519ef,
-          0x40459a01,
-          0x40461a25,
-          0x40469a45,
-          0x40471a53,
-          0x40479a7a,
-          0x40481ab7,
-          0x40489ad0,
-          0x40491ae7,
-          0x40499b01,
-          0x404a1b18,
-          0x404a9b36,
-          0x404b1b4e,
-          0x404b9b65,
-          0x404c1b7b,
-          0x404c9b8d,
-          0x404d1bae,
-          0x404d9bd0,
-          0x404e1be4,
-          0x404e9bf1,
-          0x404f1c1e,
-          0x404f9c47,
-          0x40501c71,
-          0x40509c85,
-          0x40511ca0,
-          0x40519cb0,
-          0x40521cc7,
-          0x40529ceb,
-          0x40531d03,
-          0x40539d16,
-          0x40541d2b,
-          0x40549d4e,
-          0x40551d5c,
-          0x40559d79,
-          0x40561d86,
-          0x40569d9f,
-          0x40571db7,
-          0x40579dca,
-          0x40581ddf,
-          0x40589e06,
-          0x40591e35,
-          0x40599e62,
-          0x405a1e76,
-          0x405a9e86,
-          0x405b1e9e,
-          0x405b9eaf,
-          0x405c1ec2,
-          0x405c9ed3,
-          0x405d1ee0,
-          0x405d9ef7,
-          0x405e1f17,
+          0x40451a06,
+          0x40459a18,
+          0x40461a3c,
+          0x40469a5c,
+          0x40471a6a,
+          0x40479a91,
+          0x40481ace,
+          0x40489ae7,
+          0x40491afe,
+          0x40499b18,
+          0x404a1b2f,
+          0x404a9b4d,
+          0x404b1b65,
+          0x404b9b7c,
+          0x404c1b92,
+          0x404c9ba4,
+          0x404d1bc5,
+          0x404d9be7,
+          0x404e1bfb,
+          0x404e9c08,
+          0x404f1c35,
+          0x404f9c5e,
+          0x40501c99,
+          0x40509cad,
+          0x40511cc8,
+          0x40519cd8,
+          0x40521cef,
+          0x40529d13,
+          0x40531d2b,
+          0x40539d3e,
+          0x40541d53,
+          0x40549d76,
+          0x40551d84,
+          0x40559da1,
+          0x40561dae,
+          0x40569dc7,
+          0x40571ddf,
+          0x40579df2,
+          0x40581e07,
+          0x40589e2e,
+          0x40591e5d,
+          0x40599e8a,
+          0x405a1e9e,
+          0x405a9eae,
+          0x405b1ec6,
+          0x405b9ed7,
+          0x405c1eea,
+          0x405c9f0b,
+          0x405d1f18,
+          0x405d9f2f,
+          0x405e1f6d,
           0x405e8a95,
-          0x405f1f38,
-          0x405f9f45,
-          0x40601f53,
-          0x40609f75,
-          0x40611f9d,
-          0x40619fb2,
-          0x40621fc9,
-          0x40629fda,
-          0x40631feb,
-          0x4063a000,
-          0x40642017,
-          0x4064a043,
-          0x4065205e,
-          0x4065a075,
-          0x4066208d,
-          0x4066a0b7,
-          0x406720e2,
-          0x4067a103,
-          0x40682116,
-          0x4068a137,
-          0x40692169,
-          0x4069a197,
-          0x406a21b8,
-          0x406aa1d8,
-          0x406b2360,
-          0x406ba383,
-          0x406c2399,
-          0x406ca5c5,
-          0x406d25f4,
-          0x406da61c,
-          0x406e264a,
-          0x406ea662,
-          0x406f2681,
-          0x406fa696,
-          0x407026a9,
-          0x4070a6c6,
+          0x405f1f8e,
+          0x405f9f9b,
+          0x40601fa9,
+          0x40609fcb,
+          0x4061200f,
+          0x4061a047,
+          0x4062205e,
+          0x4062a06f,
+          0x40632080,
+          0x4063a095,
+          0x406420ac,
+          0x4064a0d8,
+          0x406520f3,
+          0x4065a10a,
+          0x40662122,
+          0x4066a14c,
+          0x40672177,
+          0x4067a198,
+          0x406821ab,
+          0x4068a1cc,
+          0x406921fe,
+          0x4069a22c,
+          0x406a224d,
+          0x406aa26d,
+          0x406b23f5,
+          0x406ba418,
+          0x406c242e,
+          0x406ca690,
+          0x406d26bf,
+          0x406da6e7,
+          0x406e2715,
+          0x406ea749,
+          0x406f2768,
+          0x406fa77d,
+          0x40702790,
+          0x4070a7ad,
           0x40710800,
-          0x4071a6d8,
-          0x407226eb,
-          0x4072a704,
-          0x4073271c,
+          0x4071a7bf,
+          0x407227d2,
+          0x4072a7eb,
+          0x40732803,
           0x4073936d,
-          0x40742730,
-          0x4074a74a,
-          0x4075275b,
-          0x4075a76f,
-          0x4076277d,
+          0x40742817,
+          0x4074a831,
+          0x40752842,
+          0x4075a856,
+          0x40762864,
           0x407691aa,
-          0x407727a2,
-          0x4077a7c4,
-          0x407827df,
-          0x4078a818,
-          0x4079282f,
-          0x4079a845,
-          0x407a2851,
-          0x407aa864,
-          0x407b2879,
-          0x407ba88b,
-          0x407c28a0,
-          0x407ca8a9,
-          0x407d2152,
-          0x407d9c57,
-          0x407e27f4,
-          0x407e9e16,
-          0x407f1a67,
+          0x40772889,
+          0x4077a8ab,
+          0x407828c6,
+          0x4078a8ff,
+          0x40792916,
+          0x4079a92c,
+          0x407a2938,
+          0x407aa94b,
+          0x407b2960,
+          0x407ba972,
+          0x407c2987,
+          0x407ca990,
+          0x407d21e7,
+          0x407d9c6e,
+          0x407e28db,
+          0x407e9e3e,
+          0x407f1a7e,
           0x407f9887,
-          0x40801c2e,
-          0x40809a8f,
-          0x40811cd9,
-          0x40819c08,
-          0x40822635,
+          0x40801c45,
+          0x40809aa6,
+          0x40811d01,
+          0x40819c1f,
+          0x40822700,
           0x4082986d,
-          0x40831df1,
-          0x4083a028,
-          0x40841aa3,
-          0x40849e4e,
-          0x41f4228b,
-          0x41f9231d,
-          0x41fe2210,
-          0x41fea3ec,
-          0x41ff24dd,
-          0x420322a4,
-          0x420822c6,
-          0x4208a302,
-          0x420921f4,
-          0x4209a33c,
-          0x420a224b,
-          0x420aa22b,
-          0x420b226b,
-          0x420ba2e4,
-          0x420c24f9,
-          0x420ca3b9,
-          0x420d23d3,
-          0x420da40a,
-          0x42122424,
-          0x421724c0,
-          0x4217a466,
-          0x421c2488,
-          0x421f2443,
-          0x42212510,
-          0x422624a3,
-          0x422b25a9,
-          0x422ba572,
-          0x422c2591,
-          0x422ca54c,
-          0x422d252b,
+          0x40831e19,
+          0x4083a0bd,
+          0x40841aba,
+          0x40849e76,
+          0x40851efb,
+          0x40859ff3,
+          0x40861f4f,
+          0x40869c88,
+          0x4087272d,
+          0x4087a024,
+          0x408818aa,
+          0x41f42320,
+          0x41f923b2,
+          0x41fe22a5,
+          0x41fea481,
+          0x41ff2572,
+          0x42032339,
+          0x4208235b,
+          0x4208a397,
+          0x42092289,
+          0x4209a3d1,
+          0x420a22e0,
+          0x420aa2c0,
+          0x420b2300,
+          0x420ba379,
+          0x420c258e,
+          0x420ca44e,
+          0x420d2468,
+          0x420da49f,
+          0x421224b9,
+          0x42172555,
+          0x4217a4fb,
+          0x421c251d,
+          0x421f24d8,
+          0x422125a5,
+          0x42262538,
+          0x422b2674,
+          0x422ba622,
+          0x422c265c,
+          0x422ca5e1,
+          0x422d25c0,
+          0x422da641,
+          0x422e2607,
           0x4432072b,
           0x4432873a,
           0x44330746,
@@ -793,69 +798,69 @@
           0x4c3d136d,
           0x4c3d937c,
           0x4c3e1389,
-          0x50322b22,
-          0x5032ab31,
-          0x50332b3c,
-          0x5033ab4c,
-          0x50342b65,
-          0x5034ab7f,
-          0x50352b8d,
-          0x5035aba3,
-          0x50362bb5,
-          0x5036abcb,
-          0x50372be4,
-          0x5037abf7,
-          0x50382c0f,
-          0x5038ac20,
-          0x50392c35,
-          0x5039ac49,
-          0x503a2c69,
-          0x503aac7f,
-          0x503b2c97,
-          0x503baca9,
-          0x503c2cc5,
-          0x503cacdc,
-          0x503d2cf5,
-          0x503dad0b,
-          0x503e2d18,
-          0x503ead2e,
-          0x503f2d40,
+          0x50322c09,
+          0x5032ac18,
+          0x50332c23,
+          0x5033ac33,
+          0x50342c4c,
+          0x5034ac66,
+          0x50352c74,
+          0x5035ac8a,
+          0x50362c9c,
+          0x5036acb2,
+          0x50372ccb,
+          0x5037acde,
+          0x50382cf6,
+          0x5038ad07,
+          0x50392d1c,
+          0x5039ad30,
+          0x503a2d50,
+          0x503aad66,
+          0x503b2d7e,
+          0x503bad90,
+          0x503c2dac,
+          0x503cadc3,
+          0x503d2ddc,
+          0x503dadf2,
+          0x503e2dff,
+          0x503eae15,
+          0x503f2e27,
           0x503f8382,
-          0x50402d53,
-          0x5040ad63,
-          0x50412d7d,
-          0x5041ad8c,
-          0x50422da6,
-          0x5042adc3,
-          0x50432dd3,
-          0x5043ade3,
-          0x50442df2,
+          0x50402e3a,
+          0x5040ae4a,
+          0x50412e64,
+          0x5041ae73,
+          0x50422e8d,
+          0x5042aeaa,
+          0x50432eba,
+          0x5043aeca,
+          0x50442ed9,
           0x5044843f,
-          0x50452e06,
-          0x5045ae24,
-          0x50462e37,
-          0x5046ae4d,
-          0x50472e5f,
-          0x5047ae74,
-          0x50482e9a,
-          0x5048aea8,
-          0x50492ebb,
-          0x5049aed0,
-          0x504a2ee6,
-          0x504aaef6,
-          0x504b2f16,
-          0x504baf29,
-          0x504c2f4c,
-          0x504caf7a,
-          0x504d2f8c,
-          0x504dafa9,
-          0x504e2fc4,
-          0x504eafe0,
-          0x504f2ff2,
-          0x504fb009,
-          0x50503018,
+          0x50452eed,
+          0x5045af0b,
+          0x50462f1e,
+          0x5046af34,
+          0x50472f46,
+          0x5047af5b,
+          0x50482f81,
+          0x5048af8f,
+          0x50492fa2,
+          0x5049afb7,
+          0x504a2fcd,
+          0x504aafdd,
+          0x504b2ffd,
+          0x504bb010,
+          0x504c3033,
+          0x504cb061,
+          0x504d3073,
+          0x504db090,
+          0x504e30ab,
+          0x504eb0c7,
+          0x504f30d9,
+          0x504fb0f0,
+          0x505030ff,
           0x505086ef,
-          0x5051302b,
+          0x50513112,
           0x58320ec9,
           0x68320e8b,
           0x68328c25,
@@ -1218,6 +1223,7 @@
           "BIO_NOT_SET\\0"
           "BLOCK_CIPHER_PAD_IS_WRONG\\0"
           "BUFFERED_MESSAGES_ON_CIPHER_CHANGE\\0"
+          "CANNOT_PARSE_LEAF_CERT\\0"
           "CA_DN_LENGTH_MISMATCH\\0"
           "CA_DN_TOO_LONG\\0"
           "CCS_RECEIVED_EARLY\\0"
@@ -1261,6 +1267,7 @@
           "INVALID_COMPRESSION_LIST\\0"
           "INVALID_MESSAGE\\0"
           "INVALID_OUTER_RECORD_TYPE\\0"
+          "INVALID_SCT_LIST\\0"
           "INVALID_SSL_SESSION\\0"
           "INVALID_TICKET_KEYS_LENGTH\\0"
           "LENGTH_MISMATCH\\0"
@@ -1290,15 +1297,19 @@
           "NO_RENEGOTIATION\\0"
           "NO_REQUIRED_DIGEST\\0"
           "NO_SHARED_CIPHER\\0"
+          "NO_SHARED_GROUP\\0"
           "NULL_SSL_CTX\\0"
           "NULL_SSL_METHOD_PASSED\\0"
           "OLD_SESSION_CIPHER_NOT_RETURNED\\0"
+          "OLD_SESSION_PRF_HASH_MISMATCH\\0"
           "OLD_SESSION_VERSION_NOT_RETURNED\\0"
           "PARSE_TLSEXT\\0"
           "PATH_TOO_LONG\\0"
           "PEER_DID_NOT_RETURN_A_CERTIFICATE\\0"
           "PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE\\0"
+          "PRE_SHARED_KEY_MUST_BE_LAST\\0"
           "PROTOCOL_IS_SHUTDOWN\\0"
+          "PSK_IDENTITY_BINDER_COUNT_MISMATCH\\0"
           "PSK_IDENTITY_NOT_FOUND\\0"
           "PSK_NO_CLIENT_CB\\0"
           "PSK_NO_SERVER_CB\\0"
@@ -1350,7 +1361,9 @@
           "TLSV1_ALERT_USER_CANCELLED\\0"
           "TLSV1_BAD_CERTIFICATE_HASH_VALUE\\0"
           "TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE\\0"
+          "TLSV1_CERTIFICATE_REQUIRED\\0"
           "TLSV1_CERTIFICATE_UNOBTAINABLE\\0"
+          "TLSV1_UNKNOWN_PSK_IDENTITY\\0"
           "TLSV1_UNRECOGNIZED_NAME\\0"
           "TLSV1_UNSUPPORTED_EXTENSION\\0"
           "TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST\\0"
@@ -1358,6 +1371,7 @@
           "TOO_MANY_EMPTY_FRAGMENTS\\0"
           "TOO_MANY_KEY_UPDATES\\0"
           "TOO_MANY_WARNING_ALERTS\\0"
+          "TOO_MUCH_SKIPPED_EARLY_DATA\\0"
           "UNABLE_TO_FIND_ECDH_PARAMETERS\\0"
           "UNEXPECTED_EXTENSION\\0"
           "UNEXPECTED_MESSAGE\\0"
diff --git a/src/ruby/lib/grpc/generic/active_call.rb b/src/ruby/lib/grpc/generic/active_call.rb
index 87b29c2..10eb70b 100644
--- a/src/ruby/lib/grpc/generic/active_call.rb
+++ b/src/ruby/lib/grpc/generic/active_call.rb
@@ -480,7 +480,20 @@
     def bidi_streamer(requests, metadata: {}, &blk)
       raise_error_if_already_executed
       # Metadata might have already been sent if this is an operation view
-      merge_metadata_and_send_if_not_already_sent(metadata)
+      begin
+        merge_metadata_and_send_if_not_already_sent(metadata)
+      rescue GRPC::Core::CallError => e
+        batch_result = @call.run_batch(RECV_STATUS_ON_CLIENT => nil)
+        set_input_stream_done
+        set_output_stream_done
+        attach_status_results_and_complete_call(batch_result)
+        raise e
+      rescue => e
+        set_input_stream_done
+        set_output_stream_done
+        raise e
+      end
+
       bd = BidiCall.new(@call,
                         @marshal,
                         @unmarshal,
diff --git a/src/ruby/spec/generic/client_stub_spec.rb b/src/ruby/spec/generic/client_stub_spec.rb
index 42cff40..e1e7a53 100644
--- a/src/ruby/spec/generic/client_stub_spec.rb
+++ b/src/ruby/spec/generic/client_stub_spec.rb
@@ -616,8 +616,22 @@
         th.join
       end
 
-      # TODO: add test for metadata-related ArgumentError in a bidi call once
-      # issue mentioned in https://github.com/grpc/grpc/issues/10526 is fixed
+      it 'should raise ArgumentError if metadata contains invalid values' do
+        @metadata.merge!(k3: 3)
+        stub = GRPC::ClientStub.new(@host, :this_channel_is_insecure)
+        expect do
+          get_responses(stub).collect { |r| r }
+        end.to raise_error(ArgumentError,
+                           /Header values must be of type string or array/)
+      end
+
+      it 'terminates if the call fails to start' do
+        # don't start the server
+        stub = GRPC::ClientStub.new(@host, :this_channel_is_insecure)
+        expect do
+          get_responses(stub, deadline: from_relative_time(0)).collect { |r| r }
+        end.to raise_error(GRPC::BadStatus)
+      end
 
       it 'should send metadata to the server ok' do
         th = run_bidi_streamer_echo_ping_pong(@sent_msgs, @pass, true,
@@ -630,9 +644,9 @@
     end
 
     describe 'without a call operation' do
-      def get_responses(stub)
+      def get_responses(stub, deadline: nil)
         e = stub.bidi_streamer(@method, @sent_msgs, noop, noop,
-                               metadata: @metadata)
+                               metadata: @metadata, deadline: deadline)
         expect(e).to be_a(Enumerator)
         e
       end
@@ -644,10 +658,10 @@
       after(:each) do
         @op.wait # make sure wait doesn't hang
       end
-      def get_responses(stub, run_start_call_first: false)
+      def get_responses(stub, run_start_call_first: false, deadline: nil)
         @op = stub.bidi_streamer(@method, @sent_msgs, noop, noop,
                                  return_op: true,
-                                 metadata: @metadata)
+                                 metadata: @metadata, deadline: deadline)
         expect(@op).to be_a(GRPC::ActiveCall::Operation)
         @op.start_call if run_start_call_first
         e = @op.execute
diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template
index 3d54534..cfc13cf 100644
--- a/templates/gRPC-Core.podspec.template
+++ b/templates/gRPC-Core.podspec.template
@@ -135,7 +135,7 @@
       ss.header_mappings_dir = '.'
       ss.libraries = 'z'
       ss.dependency "#{s.name}/Interface", version
-      ss.dependency 'BoringSSL', '~> 8.0'
+      ss.dependency 'BoringSSL', '~> 9.0'
       ss.dependency 'nanopb', '~> 0.3'
 
       # To save you from scrolling, this is the last part of the podspec.
diff --git "a/templates/src/objective-c/\041ProtoCompiler-gRPCPlugin.podspec.template" "b/templates/src/objective-c/\041ProtoCompiler-gRPCPlugin.podspec.template"
index 24c167d..b822341 100644
--- "a/templates/src/objective-c/\041ProtoCompiler-gRPCPlugin.podspec.template"
+++ "b/templates/src/objective-c/\041ProtoCompiler-gRPCPlugin.podspec.template"
@@ -103,7 +103,7 @@
     s.preserve_paths = plugin
 
     # Restrict the protoc version to the one supported by this plugin.
-    s.dependency '!ProtoCompiler', '3.2.0'
+    s.dependency '!ProtoCompiler', '3.3.0'
     # For the Protobuf dependency not to complain:
     s.ios.deployment_target = '7.0'
     s.osx.deployment_target = '10.9'
diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc
index 2f3acb6..4fef535 100644
--- a/test/cpp/end2end/grpclb_end2end_test.cc
+++ b/test/cpp/end2end/grpclb_end2end_test.cc
@@ -185,11 +185,12 @@
         shutdown_(false) {}
 
   Status BalanceLoad(ServerContext* context, Stream* stream) override {
-    gpr_log(GPR_INFO, "LB: BalanceLoad");
+    gpr_log(GPR_INFO, "LB[%p]: BalanceLoad", this);
     LoadBalanceRequest request;
     stream->Read(&request);
     IncreaseRequestCount();
-    gpr_log(GPR_INFO, "LB: recv msg '%s'", request.DebugString().c_str());
+    gpr_log(GPR_INFO, "LB[%p]: recv msg '%s'", this,
+            request.DebugString().c_str());
 
     if (client_load_reporting_interval_seconds_ > 0) {
       LoadBalanceResponse initial_response;
@@ -220,7 +221,7 @@
     if (client_load_reporting_interval_seconds_ > 0) {
       request.Clear();
       stream->Read(&request);
-      gpr_log(GPR_INFO, "LB: recv client load report msg: '%s'",
+      gpr_log(GPR_INFO, "LB[%p]: recv client load report msg: '%s'", this,
               request.DebugString().c_str());
       GPR_ASSERT(request.has_client_stats());
       // We need to acquire the lock here in order to prevent the notify_one
@@ -244,7 +245,7 @@
       load_report_cond_.notify_one();
     }
   done:
-    gpr_log(GPR_INFO, "LB: done");
+    gpr_log(GPR_INFO, "LB[%p]: done", this);
     return Status::OK;
   }
 
@@ -259,7 +260,7 @@
     std::unique_lock<std::mutex> lock(mu_);
     const bool prev = !shutdown_;
     shutdown_ = true;
-    gpr_log(GPR_INFO, "LB: shut down");
+    gpr_log(GPR_INFO, "LB[%p]: shut down", this);
     return prev;
   }
 
@@ -296,13 +297,13 @@
  private:
   void SendResponse(Stream* stream, const LoadBalanceResponse& response,
                     int delay_ms) {
-    gpr_log(GPR_INFO, "LB: sleeping for %d ms...", delay_ms);
+    gpr_log(GPR_INFO, "LB[%p]: sleeping for %d ms...", this, delay_ms);
     if (delay_ms > 0) {
       gpr_sleep_until(
           gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
                        gpr_time_from_millis(delay_ms, GPR_TIMESPAN)));
     }
-    gpr_log(GPR_INFO, "LB: Woke up! Sending response '%s'",
+    gpr_log(GPR_INFO, "LB[%p]: Woke up! Sending response '%s'", this,
             response.DebugString().c_str());
     IncreaseResponseCount();
     stream->Write(response);
diff --git a/test/cpp/qps/server.h b/test/cpp/qps/server.h
index c0dac96..df27a43 100644
--- a/test/cpp/qps/server.h
+++ b/test/cpp/qps/server.h
@@ -80,8 +80,11 @@
       return false;
     }
     payload->set_type(type);
-    std::unique_ptr<char[]> body(new char[size]());
-    payload->set_body(body.get(), size);
+    // Don't waste time creating a new payload of identical size.
+    if (payload->body().length() != (size_t)size) {
+      std::unique_ptr<char[]> body(new char[size]());
+      payload->set_body(body.get(), size);
+    }
     return true;
   }
 
diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc
index 89e8e24..00105d4 100644
--- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc
+++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc
@@ -27,6 +27,11 @@
 # show current limits
 ulimit -a
 
+# Add GCP credentials for BQ access
+# pip does not install google-api-python-client properly, so use easy_install
+sudo easy_install --upgrade google-api-python-client
+export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json
+gcloud auth activate-service-account --key-file=$GOOGLE_APPLICATION_CREDENTIALS
 
 # required to build protobuf
 brew install gflags
diff --git a/tools/internal_ci/helper_scripts/prepare_build_windows.bat b/tools/internal_ci/helper_scripts/prepare_build_windows.bat
index 1634acd..69e087e 100644
--- a/tools/internal_ci/helper_scripts/prepare_build_windows.bat
+++ b/tools/internal_ci/helper_scripts/prepare_build_windows.bat
@@ -18,4 +18,14 @@
 
 bash tools/internal_ci/helper_scripts/gen_report_index.sh
 
+@rem Update DNS settings to:
+@rem 1. allow resolving metadata.google.internal hostname
+@rem 2. make fetching default GCE credential by oauth2client work
+netsh interface ip set dns "Local Area Connection 8" static 169.254.169.254 primary
+netsh interface ip add dnsservers "Local Area Connection 8" 8.8.8.8 index=2
+netsh interface ip add dnsservers "Local Area Connection 8" 8.8.4.4 index=3
+
+@rem Needed for big_query_utils
+python -m pip install google-api-python-client
+
 git submodule update --init
diff --git a/tools/internal_ci/macos/grpc_master.cfg b/tools/internal_ci/linux/pull_request/grpc_basictests_c_cpp_dbg.cfg
similarity index 85%
copy from tools/internal_ci/macos/grpc_master.cfg
copy to tools/internal_ci/linux/pull_request/grpc_basictests_c_cpp_dbg.cfg
index ce3609c..dcc6265 100644
--- a/tools/internal_ci/macos/grpc_master.cfg
+++ b/tools/internal_ci/linux/pull_request/grpc_basictests_c_cpp_dbg.cfg
@@ -15,7 +15,7 @@
 # Config file for the internal CI (in protobuf text format)
 
 # Location of the continuous shell script in repository.
-build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh"
+build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh"
 timeout_mins: 240
 action {
   define_artifacts {
@@ -26,5 +26,5 @@
 
 env_vars {
   key: "RUN_TESTS_FLAGS"
-  value: "-f basictests macos --internal_ci -j 2 --inner_jobs 4"
+  value: "-f basictests linux corelang dbg --inner_jobs 16 -j 1 --internal_ci"
 }
diff --git a/tools/internal_ci/macos/grpc_master.cfg b/tools/internal_ci/linux/pull_request/grpc_basictests_c_cpp_opt.cfg
similarity index 85%
rename from tools/internal_ci/macos/grpc_master.cfg
rename to tools/internal_ci/linux/pull_request/grpc_basictests_c_cpp_opt.cfg
index ce3609c..f60beaf 100644
--- a/tools/internal_ci/macos/grpc_master.cfg
+++ b/tools/internal_ci/linux/pull_request/grpc_basictests_c_cpp_opt.cfg
@@ -15,7 +15,7 @@
 # Config file for the internal CI (in protobuf text format)
 
 # Location of the continuous shell script in repository.
-build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh"
+build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh"
 timeout_mins: 240
 action {
   define_artifacts {
@@ -26,5 +26,5 @@
 
 env_vars {
   key: "RUN_TESTS_FLAGS"
-  value: "-f basictests macos --internal_ci -j 2 --inner_jobs 4"
+  value: "-f basictests linux corelang opt --inner_jobs 16 -j 1 --internal_ci"
 }
diff --git a/tools/internal_ci/macos/grpc_master.cfg b/tools/internal_ci/linux/pull_request/grpc_basictests_multilang.cfg
similarity index 85%
copy from tools/internal_ci/macos/grpc_master.cfg
copy to tools/internal_ci/linux/pull_request/grpc_basictests_multilang.cfg
index ce3609c..7c16cf6 100644
--- a/tools/internal_ci/macos/grpc_master.cfg
+++ b/tools/internal_ci/linux/pull_request/grpc_basictests_multilang.cfg
@@ -15,7 +15,7 @@
 # Config file for the internal CI (in protobuf text format)
 
 # Location of the continuous shell script in repository.
-build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh"
+build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh"
 timeout_mins: 240
 action {
   define_artifacts {
@@ -26,5 +26,5 @@
 
 env_vars {
   key: "RUN_TESTS_FLAGS"
-  value: "-f basictests macos --internal_ci -j 2 --inner_jobs 4"
+  value: "-f basictests linux multilang --inner_jobs 16 -j 2 --internal_ci"
 }
diff --git a/tools/internal_ci/macos/grpc_basictests.cfg b/tools/internal_ci/macos/grpc_basictests.cfg
index ce3609c..e10c2e3 100644
--- a/tools/internal_ci/macos/grpc_basictests.cfg
+++ b/tools/internal_ci/macos/grpc_basictests.cfg
@@ -16,6 +16,7 @@
 
 # Location of the continuous shell script in repository.
 build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh"
+gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json"
 timeout_mins: 240
 action {
   define_artifacts {
@@ -26,5 +27,5 @@
 
 env_vars {
   key: "RUN_TESTS_FLAGS"
-  value: "-f basictests macos --internal_ci -j 2 --inner_jobs 4"
+  value: "-f basictests macos --internal_ci -j 2 --inner_jobs 4 --bq_result_table aggregate_results"
 }
diff --git a/tools/internal_ci/windows/grpc_basictests.cfg b/tools/internal_ci/windows/grpc_basictests.cfg
index a116738..396d29e 100644
--- a/tools/internal_ci/windows/grpc_basictests.cfg
+++ b/tools/internal_ci/windows/grpc_basictests.cfg
@@ -26,5 +26,5 @@
 
 env_vars {
   key: "RUN_TESTS_FLAGS"
-  value: "-f basictests windows -j 1 --inner_jobs 8 --internal_ci"
+  value: "-f basictests windows -j 1 --inner_jobs 8 --internal_ci --bq_result_table aggregate_results"
 }
diff --git a/tools/internal_ci/macos/grpc_master.cfg b/tools/internal_ci/windows/grpc_portability.cfg
similarity index 83%
copy from tools/internal_ci/macos/grpc_master.cfg
copy to tools/internal_ci/windows/grpc_portability.cfg
index ce3609c..c395cb4 100644
--- a/tools/internal_ci/macos/grpc_master.cfg
+++ b/tools/internal_ci/windows/grpc_portability.cfg
@@ -15,8 +15,8 @@
 # Config file for the internal CI (in protobuf text format)
 
 # Location of the continuous shell script in repository.
-build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh"
-timeout_mins: 240
+build_file: "grpc/tools/internal_ci/windows/grpc_run_tests_matrix.bat"
+timeout_mins: 360
 action {
   define_artifacts {
     regex: "**/*sponge_log.xml"
@@ -26,5 +26,5 @@
 
 env_vars {
   key: "RUN_TESTS_FLAGS"
-  value: "-f basictests macos --internal_ci -j 2 --inner_jobs 4"
+  value: "-f portability windows -j 1 --inner_jobs 8 --internal_ci"
 }
diff --git a/tools/internal_ci/windows/grpc_master.cfg b/tools/internal_ci/windows/pull_request/grpc_basictests.cfg
similarity index 100%
rename from tools/internal_ci/windows/grpc_master.cfg
rename to tools/internal_ci/windows/pull_request/grpc_basictests.cfg
diff --git a/tools/internal_ci/macos/grpc_master.cfg b/tools/internal_ci/windows/pull_request/grpc_portability.cfg
similarity index 83%
copy from tools/internal_ci/macos/grpc_master.cfg
copy to tools/internal_ci/windows/pull_request/grpc_portability.cfg
index ce3609c..c395cb4 100644
--- a/tools/internal_ci/macos/grpc_master.cfg
+++ b/tools/internal_ci/windows/pull_request/grpc_portability.cfg
@@ -15,8 +15,8 @@
 # Config file for the internal CI (in protobuf text format)
 
 # Location of the continuous shell script in repository.
-build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh"
-timeout_mins: 240
+build_file: "grpc/tools/internal_ci/windows/grpc_run_tests_matrix.bat"
+timeout_mins: 360
 action {
   define_artifacts {
     regex: "**/*sponge_log.xml"
@@ -26,5 +26,5 @@
 
 env_vars {
   key: "RUN_TESTS_FLAGS"
-  value: "-f basictests macos --internal_ci -j 2 --inner_jobs 4"
+  value: "-f portability windows -j 1 --inner_jobs 8 --internal_ci"
 }