Merge pull request #13313 from murgatroid99/uv_assertion_fixes

Fix timer freed early in uv pollset
diff --git a/src/core/ext/filters/client_channel/uri_parser.cc b/src/core/ext/filters/client_channel/uri_parser.cc
index 917e653..1cc52de 100644
--- a/src/core/ext/filters/client_channel/uri_parser.cc
+++ b/src/core/ext/filters/client_channel/uri_parser.cc
@@ -59,7 +59,9 @@
 static char* decode_and_copy_component(grpc_exec_ctx* exec_ctx, const char* src,
                                        size_t begin, size_t end) {
   grpc_slice component =
-      grpc_slice_from_copied_buffer(src + begin, end - begin);
+      (begin == NOT_SET || end == NOT_SET)
+          ? grpc_empty_slice()
+          : grpc_slice_from_copied_buffer(src + begin, end - begin);
   grpc_slice decoded_component =
       grpc_permissive_percent_decode_slice(component);
   char* out = grpc_dump_slice(decoded_component, GPR_DUMP_ASCII);
diff --git a/src/core/lib/iomgr/lockfree_event.cc b/src/core/lib/iomgr/lockfree_event.cc
index 98e19f8..40e2ed6 100644
--- a/src/core/lib/iomgr/lockfree_event.cc
+++ b/src/core/lib/iomgr/lockfree_event.cc
@@ -57,13 +57,30 @@
 
 namespace grpc_core {
 
+LockfreeEvent::LockfreeEvent() {
+  /* Perform an atomic store to start the state machine.
+
+     Note carefully that LockfreeEvent *MAY* be used whilst in a destroyed
+     state, while a file descriptor is on a freelist. In such a state it may
+     be SetReady'd, and so we need to perform an atomic operation here to
+     ensure no races */
+  gpr_atm_no_barrier_store(&state_, kClosureNotReady);
+}
+
 LockfreeEvent::~LockfreeEvent() {
-  gpr_atm curr = gpr_atm_no_barrier_load(&state_);
-  if (curr & kShutdownBit) {
-    GRPC_ERROR_UNREF((grpc_error*)(curr & ~kShutdownBit));
-  } else {
-    GPR_ASSERT(curr == kClosureNotReady || curr == kClosureReady);
-  }
+  gpr_atm curr;
+  do {
+    curr = gpr_atm_no_barrier_load(&state_);
+    if (curr & kShutdownBit) {
+      GRPC_ERROR_UNREF((grpc_error*)(curr & ~kShutdownBit));
+    } else {
+      GPR_ASSERT(curr == kClosureNotReady || curr == kClosureReady);
+    }
+    /* we CAS in a shutdown, no error value here. If this event is interacted
+       with post-deletion (see the note in the constructor) we want the bit
+       pattern to prevent error retention in a deleted object */
+  } while (!gpr_atm_no_barrier_cas(&state_, curr,
+                                   kShutdownBit /* shutdown, no error */));
 }
 
 void LockfreeEvent::NotifyOn(grpc_exec_ctx* exec_ctx, grpc_closure* closure) {
diff --git a/src/core/lib/iomgr/lockfree_event.h b/src/core/lib/iomgr/lockfree_event.h
index 47d0089..c667dcd 100644
--- a/src/core/lib/iomgr/lockfree_event.h
+++ b/src/core/lib/iomgr/lockfree_event.h
@@ -29,7 +29,7 @@
 
 class LockfreeEvent {
  public:
-  LockfreeEvent() = default;
+  LockfreeEvent();
   ~LockfreeEvent();
 
   LockfreeEvent(const LockfreeEvent&) = delete;
@@ -46,7 +46,7 @@
  private:
   enum State { kClosureNotReady = 0, kClosureReady = 2, kShutdownBit = 1 };
 
-  gpr_atm state_ = kClosureNotReady;
+  gpr_atm state_;
 };
 
 }  // namespace grpc_core
diff --git a/test/core/end2end/data/client_certs.cc b/test/core/end2end/data/client_certs.cc
index 6e61501..7e0b10d 100644
--- a/test/core/end2end/data/client_certs.cc
+++ b/test/core/end2end/data/client_certs.cc
@@ -16,9 +16,7 @@
  *
  */
 
-#include "test/core/end2end/data/ssl_test_data.h"
-
-const char test_self_signed_client_cert[] = {
+extern "C" const char test_self_signed_client_cert[] = {
     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43,
     0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
     0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, 0x6f, 0x44, 0x43, 0x43,
@@ -102,7 +100,7 @@
     0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
     0x0a, 0x00};
 
-const char test_self_signed_client_key[] = {
+extern "C" const char test_self_signed_client_key[] = {
     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x50,
     0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d,
     0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, 0x64, 0x77, 0x49, 0x42,
@@ -181,7 +179,7 @@
     0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d,
     0x2d, 0x2d, 0x2d, 0x0a, 0x00};
 
-const char test_signed_client_cert[] = {
+extern "C" const char test_signed_client_cert[] = {
     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43,
     0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
     0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, 0x48, 0x7a, 0x43, 0x43,
@@ -250,7 +248,7 @@
     0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45,
     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x00};
 
-const char test_signed_client_key[] = {
+extern "C" const char test_signed_client_key[] = {
     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x50,
     0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d,
     0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, 0x65, 0x51, 0x49, 0x42,
diff --git a/test/core/end2end/data/server1_cert.cc b/test/core/end2end/data/server1_cert.cc
index 5e017c4..dd09810 100644
--- a/test/core/end2end/data/server1_cert.cc
+++ b/test/core/end2end/data/server1_cert.cc
@@ -16,9 +16,7 @@
  *
  */
 
-#include "test/core/end2end/data/ssl_test_data.h"
-
-const char test_server1_cert[] = {
+extern "C" const char test_server1_cert[] = {
     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43,
     0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
     0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, 0x6e, 0x44, 0x43, 0x43,
diff --git a/test/core/end2end/data/server1_key.cc b/test/core/end2end/data/server1_key.cc
index 92a77aa..59dcaf6 100644
--- a/test/core/end2end/data/server1_key.cc
+++ b/test/core/end2end/data/server1_key.cc
@@ -16,9 +16,7 @@
  *
  */
 
-#include "test/core/end2end/data/ssl_test_data.h"
-
-const char test_server1_key[] = {
+extern "C" const char test_server1_key[] = {
     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x52,
     0x53, 0x41, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b,
     0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43,
diff --git a/test/core/end2end/data/test_root_cert.cc b/test/core/end2end/data/test_root_cert.cc
index 81ca410..36fca2e 100644
--- a/test/core/end2end/data/test_root_cert.cc
+++ b/test/core/end2end/data/test_root_cert.cc
@@ -16,9 +16,7 @@
  *
  */
 
-#include "test/core/end2end/data/ssl_test_data.h"
-
-const char test_root_cert[] = {
+extern "C" const char test_root_cert[] = {
     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43,
     0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
     0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, 0x49, 0x7a, 0x43, 0x43,
diff --git a/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile
new file mode 100644
index 0000000..0251b2b
--- /dev/null
+++ b/tools/dockerfile/grpc_artifact_linux_x64/Dockerfile
@@ -0,0 +1,88 @@
+# Copyright 2016 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.
+
+# Docker file for building gRPC artifacts.
+
+FROM debian:jessie
+
+RUN apt-get update && apt-get install debian-keyring && apt-key update
+
+# Install Git and basic packages.
+RUN apt-get update && apt-key update && apt-get install -y \
+  autoconf \
+  autotools-dev \
+  build-essential \
+  bzip2 \
+  clang \
+  curl \
+  gcc \
+  gcc-multilib \
+  git \
+  golang \
+  libc6 \
+  libc6-dbg \
+  libc6-dev \
+  libgtest-dev \
+  libtool \
+  make \
+  perl \
+  strace \
+  python-dev \
+  python-setuptools \
+  python-yaml \
+  telnet \
+  unzip \
+  wget \
+  zip && apt-get clean
+
+# Install Node dependencies
+RUN touch .profile
+RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.25.4/install.sh | bash
+RUN /bin/bash -l -c "nvm install 8 && npm install -g node-pre-gyp"
+
+
+##################
+# Ruby dependencies
+
+# Install rvm
+RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
+RUN \curl -sSL https://get.rvm.io | bash -s stable
+
+# Install Ruby 2.1
+RUN /bin/bash -l -c "rvm install ruby-2.1"
+RUN /bin/bash -l -c "rvm use --default ruby-2.1"
+RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
+RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc"
+RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc"
+RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc"
+
+
+##################
+# PHP dependencies
+
+RUN apt-get update && apt-get install -y \
+    php5 php5-dev php-pear phpunit
+
+##################
+# Install cross compiler for ARM
+
+RUN echo 'deb http://emdebian.org/tools/debian/ jessie main' | tee -a /etc/apt/sources.list.d/crosstools.list && \
+  curl http://emdebian.org/tools/debian/emdebian-toolchain-archive.key | apt-key add -
+
+RUN dpkg --add-architecture armhf && apt-get update && apt-get install -y crossbuild-essential-armhf
+
+RUN mkdir /var/local/jenkins
+
+# Define the default command.
+CMD ["bash"]
diff --git a/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile
new file mode 100644
index 0000000..2d179c8
--- /dev/null
+++ b/tools/dockerfile/grpc_artifact_linux_x86/Dockerfile
@@ -0,0 +1,73 @@
+# Copyright 2016 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.
+
+# Docker file for building gRPC artifacts.
+
+FROM 32bit/debian:jessie
+
+RUN apt-get update && apt-get install debian-keyring && apt-key update
+
+# Install Git and basic packages.
+RUN apt-get update && apt-key update && apt-get install -y \
+  autoconf \
+  autotools-dev \
+  build-essential \
+  bzip2 \
+  clang \
+  curl \
+  gcc \
+  gcc-multilib \
+  git \
+  golang \
+  libc6 \
+  libc6-dbg \
+  libc6-dev \
+  libgtest-dev \
+  libtool \
+  make \
+  perl \
+  strace \
+  python-dev \
+  python-setuptools \
+  python-yaml \
+  telnet \
+  unzip \
+  wget \
+  zip && apt-get clean
+
+# Install Node dependencies
+RUN touch .profile
+RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.25.4/install.sh | bash
+RUN /bin/bash -l -c "nvm install 8 && npm install -g node-pre-gyp"
+
+
+##################
+# Ruby dependencies
+
+# Install rvm
+RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
+RUN \curl -sSL https://get.rvm.io | bash -s stable
+
+# Install Ruby 2.1
+RUN /bin/bash -l -c "rvm install ruby-2.1"
+RUN /bin/bash -l -c "rvm use --default ruby-2.1"
+RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
+RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc"
+RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc"
+RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc"
+
+RUN mkdir /var/local/jenkins
+
+# Define the default command.
+CMD ["bash"]