浏览代码

Merge github.com:grpc/grpc into delayed-write

Craig Tiller 9 年之前
父节点
当前提交
89a717f615

+ 19 - 7
setup.py

@@ -62,15 +62,17 @@ import commands
 import grpc_core_dependencies
 import grpc_core_dependencies
 import grpc_version
 import grpc_version
 
 
-# TODO(atash) make this conditional on being on a mingw32 build
-_unixccompiler_patch.monkeypatch_unix_compiler()
+if 'win32' in sys.platform:
+  _unixccompiler_patch.monkeypatch_unix_compiler()
 
 
 
 
 LICENSE = '3-clause BSD'
 LICENSE = '3-clause BSD'
 
 
 # Environment variable to determine whether or not the Cython extension should
 # Environment variable to determine whether or not the Cython extension should
 # *use* Cython or use the generated C files. Note that this requires the C files
 # *use* Cython or use the generated C files. Note that this requires the C files
-# to have been generated by building first *with* Cython support.
+# to have been generated by building first *with* Cython support. Even if this
+# is set to false, if the script detects that the generated `.c` file isn't
+# present, then it will still attempt to use Cython.
 BUILD_WITH_CYTHON = os.environ.get('GRPC_PYTHON_BUILD_WITH_CYTHON', False)
 BUILD_WITH_CYTHON = os.environ.get('GRPC_PYTHON_BUILD_WITH_CYTHON', False)
 
 
 # Environment variable to determine whether or not to enable coverage analysis
 # Environment variable to determine whether or not to enable coverage analysis
@@ -146,10 +148,20 @@ def cython_extensions(module_names, extra_sources, include_dirs,
   if ENABLE_CYTHON_TRACING:
   if ENABLE_CYTHON_TRACING:
     define_macros = define_macros + [('CYTHON_TRACE_NOGIL', 1)]
     define_macros = define_macros + [('CYTHON_TRACE_NOGIL', 1)]
     cython_compiler_directives['linetrace'] = True
     cython_compiler_directives['linetrace'] = True
-  file_extension = 'pyx' if build_with_cython else 'c'
-  module_files = [os.path.join(PYTHON_STEM,
-                               name.replace('.', '/') + '.' + file_extension)
-                  for name in module_names]
+  pyx_module_files = [os.path.join(PYTHON_STEM,
+                                   name.replace('.', '/') + '.pyx')
+                      for name in module_names]
+  c_module_files = [os.path.join(PYTHON_STEM,
+                                 name.replace('.', '/') + '.c')
+                    for name in module_names]
+  if not build_with_cython:
+    for module_file in c_module_files:
+      if not os.path.isfile(module_file):
+        sys.stderr.write('Cython-generated files are missing; '
+                         'forcing Cython build...\n')
+        build_with_cython = True
+        break
+  module_files = pyx_module_files if build_with_cython else c_module_files
   extensions = [
   extensions = [
       _extension.Extension(
       _extension.Extension(
           name=module_name,
           name=module_name,

+ 43 - 79
src/core/lib/support/time.c

@@ -80,103 +80,67 @@ gpr_timespec gpr_inf_past(gpr_clock_type type) {
   return out;
   return out;
 }
 }
 
 
-/* TODO(ctiller): consider merging _nanos, _micros, _millis into a single
-   function for maintainability. Similarly for _seconds, _minutes, and _hours */
-
-gpr_timespec gpr_time_from_nanos(int64_t ns, gpr_clock_type type) {
-  gpr_timespec result;
-  result.clock_type = type;
-  if (ns == INT64_MAX) {
-    result = gpr_inf_future(type);
-  } else if (ns == INT64_MIN) {
-    result = gpr_inf_past(type);
-  } else if (ns >= 0) {
-    result.tv_sec = ns / GPR_NS_PER_SEC;
-    result.tv_nsec = (int32_t)(ns - result.tv_sec * GPR_NS_PER_SEC);
+static gpr_timespec to_seconds_from_sub_second_time(int64_t time_in_units,
+                                                    int64_t units_per_sec,
+                                                    gpr_clock_type type) {
+  gpr_timespec out;
+  if (time_in_units == INT64_MAX) {
+    out = gpr_inf_future(type);
+  } else if (time_in_units == INT64_MIN) {
+    out = gpr_inf_past(type);
   } else {
   } else {
-    /* Calculation carefully formulated to avoid any possible under/overflow. */
-    result.tv_sec = (-(999999999 - (ns + GPR_NS_PER_SEC)) / GPR_NS_PER_SEC) - 1;
-    result.tv_nsec = (int32_t)(ns - result.tv_sec * GPR_NS_PER_SEC);
+    if (time_in_units >= 0) {
+      out.tv_sec = time_in_units / units_per_sec;
+    } else {
+      out.tv_sec = (-((units_per_sec - 1) - (time_in_units + units_per_sec)) /
+                    units_per_sec) -
+                   1;
+    }
+    out.tv_nsec = (int32_t)((time_in_units - out.tv_sec * units_per_sec) *
+                            GPR_NS_PER_SEC / units_per_sec);
+    out.clock_type = type;
   }
   }
-  return result;
+  return out;
 }
 }
 
 
-gpr_timespec gpr_time_from_micros(int64_t us, gpr_clock_type type) {
-  gpr_timespec result;
-  result.clock_type = type;
-  if (us == INT64_MAX) {
-    result = gpr_inf_future(type);
-  } else if (us == INT64_MIN) {
-    result = gpr_inf_past(type);
-  } else if (us >= 0) {
-    result.tv_sec = us / 1000000;
-    result.tv_nsec = (int32_t)((us - result.tv_sec * 1000000) * 1000);
+static gpr_timespec to_seconds_from_above_second_time(int64_t time_in_units,
+                                                      int64_t secs_per_unit,
+                                                      gpr_clock_type type) {
+  gpr_timespec out;
+  if (time_in_units >= INT64_MAX / secs_per_unit) {
+    out = gpr_inf_future(type);
+  } else if (time_in_units <= INT64_MIN / secs_per_unit) {
+    out = gpr_inf_past(type);
   } else {
   } else {
-    /* Calculation carefully formulated to avoid any possible under/overflow. */
-    result.tv_sec = (-(999999 - (us + 1000000)) / 1000000) - 1;
-    result.tv_nsec = (int32_t)((us - result.tv_sec * 1000000) * 1000);
+    out.tv_sec = time_in_units * secs_per_unit;
+    out.tv_nsec = 0;
+    out.clock_type = type;
   }
   }
-  return result;
+  return out;
+}
+
+gpr_timespec gpr_time_from_nanos(int64_t ns, gpr_clock_type type) {
+  return to_seconds_from_sub_second_time(ns, GPR_NS_PER_SEC, type);
+}
+
+gpr_timespec gpr_time_from_micros(int64_t us, gpr_clock_type type) {
+  return to_seconds_from_sub_second_time(us, GPR_US_PER_SEC, type);
 }
 }
 
 
 gpr_timespec gpr_time_from_millis(int64_t ms, gpr_clock_type type) {
 gpr_timespec gpr_time_from_millis(int64_t ms, gpr_clock_type type) {
-  gpr_timespec result;
-  result.clock_type = type;
-  if (ms == INT64_MAX) {
-    result = gpr_inf_future(type);
-  } else if (ms == INT64_MIN) {
-    result = gpr_inf_past(type);
-  } else if (ms >= 0) {
-    result.tv_sec = ms / 1000;
-    result.tv_nsec = (int32_t)((ms - result.tv_sec * 1000) * 1000000);
-  } else {
-    /* Calculation carefully formulated to avoid any possible under/overflow. */
-    result.tv_sec = (-(999 - (ms + 1000)) / 1000) - 1;
-    result.tv_nsec = (int32_t)((ms - result.tv_sec * 1000) * 1000000);
-  }
-  return result;
+  return to_seconds_from_sub_second_time(ms, GPR_MS_PER_SEC, type);
 }
 }
 
 
 gpr_timespec gpr_time_from_seconds(int64_t s, gpr_clock_type type) {
 gpr_timespec gpr_time_from_seconds(int64_t s, gpr_clock_type type) {
-  gpr_timespec result;
-  result.clock_type = type;
-  if (s == INT64_MAX) {
-    result = gpr_inf_future(type);
-  } else if (s == INT64_MIN) {
-    result = gpr_inf_past(type);
-  } else {
-    result.tv_sec = s;
-    result.tv_nsec = 0;
-  }
-  return result;
+  return to_seconds_from_sub_second_time(s, 1, type);
 }
 }
 
 
 gpr_timespec gpr_time_from_minutes(int64_t m, gpr_clock_type type) {
 gpr_timespec gpr_time_from_minutes(int64_t m, gpr_clock_type type) {
-  gpr_timespec result;
-  result.clock_type = type;
-  if (m >= INT64_MAX / 60) {
-    result = gpr_inf_future(type);
-  } else if (m <= INT64_MIN / 60) {
-    result = gpr_inf_past(type);
-  } else {
-    result.tv_sec = m * 60;
-    result.tv_nsec = 0;
-  }
-  return result;
+  return to_seconds_from_above_second_time(m, 60, type);
 }
 }
 
 
 gpr_timespec gpr_time_from_hours(int64_t h, gpr_clock_type type) {
 gpr_timespec gpr_time_from_hours(int64_t h, gpr_clock_type type) {
-  gpr_timespec result;
-  result.clock_type = type;
-  if (h >= INT64_MAX / 3600) {
-    result = gpr_inf_future(type);
-  } else if (h <= INT64_MIN / 3600) {
-    result = gpr_inf_past(type);
-  } else {
-    result.tv_sec = h * 3600;
-    result.tv_nsec = 0;
-  }
-  return result;
+  return to_seconds_from_above_second_time(h, 3600, type);
 }
 }
 
 
 gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b) {
 gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b) {

+ 25 - 73
src/python/grpcio/_unixccompiler_patch.py

@@ -38,84 +38,36 @@ import shutil
 import sys
 import sys
 import tempfile
 import tempfile
 
 
+def _unix_commandfile_spawn(self, command):
+  """Wrapper around distutils.util.spawn that attempts to use command files.
 
 
-def _unix_piecemeal_link(
-    self, target_desc, objects, output_filename, output_dir=None,
-    libraries=None, library_dirs=None, runtime_library_dirs=None,
-    export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None,
-    build_temp=None, target_lang=None):
-  """`link` externalized method taken almost verbatim from UnixCCompiler.
+  Meant to replace the CCompiler method `spawn` on UnixCCompiler and its
+  derivatives (e.g. the MinGW32 compiler).
 
 
-  Modifies the link command for unix-like compilers by using a command file so
-  that long command line argument strings don't break the command shell's
-  ARG_MAX character limit.
+  Some commands like `gcc` (and friends like `clang`) support command files to
+  work around shell command length limits.
   """
   """
-  objects, output_dir = self._fix_object_args(objects, output_dir)
-  libraries, library_dirs, runtime_library_dirs = self._fix_lib_args(
-      libraries, library_dirs, runtime_library_dirs)
-  # filter out standard library paths, which are not explicitely needed
-  # for linking
-  library_dirs = [dir for dir in library_dirs
-                  if not dir in ('/lib', '/lib64', '/usr/lib', '/usr/lib64')]
-  runtime_library_dirs = [dir for dir in runtime_library_dirs
-                          if not dir in ('/lib', '/lib64', '/usr/lib', '/usr/lib64')]
-  lib_opts = ccompiler.gen_lib_options(self, library_dirs, runtime_library_dirs,
-                             libraries)
-  if (not (isinstance(output_dir, str) or isinstance(output_dir, bytes))
-      and output_dir is not None):
-    raise TypeError("'output_dir' must be a string or None")
-  if output_dir is not None:
-    output_filename = os.path.join(output_dir, output_filename)
-
-  if self._need_link(objects, output_filename):
-    ld_args = (objects + self.objects +
-               lib_opts + ['-o', output_filename])
-    if debug:
-      ld_args[:0] = ['-g']
-    if extra_preargs:
-      ld_args[:0] = extra_preargs
-    if extra_postargs:
-      ld_args.extend(extra_postargs)
-    self.mkpath(os.path.dirname(output_filename))
-    try:
-      if target_desc == ccompiler.CCompiler.EXECUTABLE:
-        linker = self.linker_exe[:]
-      else:
-        linker = self.linker_so[:]
-      if target_lang == "c++" and self.compiler_cxx:
-        # skip over environment variable settings if /usr/bin/env
-        # is used to set up the linker's environment.
-        # This is needed on OSX. Note: this assumes that the
-        # normal and C++ compiler have the same environment
-        # settings.
-        i = 0
-        if os.path.basename(linker[0]) == "env":
-          i = 1
-          while '=' in linker[i]:
-            i = i + 1
-
-        linker[i] = self.compiler_cxx[i]
-
-      if sys.platform == 'darwin':
-        import _osx_support
-        linker = _osx_support.compiler_fixup(linker, ld_args)
-
-      temporary_directory = tempfile.mkdtemp()
-      command_filename = os.path.abspath(
-          os.path.join(temporary_directory, 'command'))
-      with open(command_filename, 'w') as command_file:
-        escaped_ld_args = [arg.replace('\\', '\\\\') for arg in ld_args]
-        command_file.write(' '.join(escaped_ld_args))
-      self.spawn(linker + ['@{}'.format(command_filename)])
-    except errors.DistutilsExecError:
-      raise ccompiler.LinkError
+  command_base = os.path.basename(command[0].strip())
+  if command_base == 'ccache':
+    command_base = command[:2]
+    command_args = command[2:]
+  elif command_base.startswith('ccache') or command_base in ['gcc', 'clang', 'clang++', 'g++']:
+    command_base = command[:1]
+    command_args = command[1:]
   else:
   else:
-    log.debug("skipping %s (up-to-date)", output_filename)
+    return ccompiler.CCompiler.spawn(self, command)
+  temporary_directory = tempfile.mkdtemp()
+  command_filename = os.path.abspath(os.path.join(temporary_directory, 'command'))
+  with open(command_filename, 'w') as command_file:
+    escaped_args = [arg.replace('\\', '\\\\') for arg in command_args]
+    command_file.write(' '.join(escaped_args))
+  modified_command = command_base + ['@{}'.format(command_filename)]
+  result = ccompiler.CCompiler.spawn(self, modified_command)
+  shutil.rmtree(temporary_directory)
+  return result
+
 
 
-# TODO(atash) try replacing this monkeypatch of the compiler harness' link
-# operation with a monkeypatch of the distutils `spawn` that applies
-# command-argument-file hacks where it can. Might be cleaner.
 def monkeypatch_unix_compiler():
 def monkeypatch_unix_compiler():
   """Monkeypatching is dumb, but it's either that or we become maintainers of
   """Monkeypatching is dumb, but it's either that or we become maintainers of
      something much, much bigger."""
      something much, much bigger."""
-  unixccompiler.UnixCCompiler.link = _unix_piecemeal_link
+  unixccompiler.UnixCCompiler.spawn = _unix_commandfile_spawn

+ 1 - 1
test/core/end2end/dualstack_socket_test.c

@@ -273,7 +273,7 @@ void test_connect(const char *server_host, const char *client_host, int port,
 }
 }
 
 
 int external_dns_works(const char *host) {
 int external_dns_works(const char *host) {
-  grpc_resolved_addresses *res;
+  grpc_resolved_addresses *res = NULL;
   grpc_error *error = grpc_blocking_resolve_address(host, "80", &res);
   grpc_error *error = grpc_blocking_resolve_address(host, "80", &res);
   GRPC_ERROR_UNREF(error);
   GRPC_ERROR_UNREF(error);
   if (res != NULL) {
   if (res != NULL) {

+ 1 - 1
test/core/surface/sequential_connectivity_test.c

@@ -154,7 +154,7 @@ static void secure_test_add_port(grpc_server *server, const char *addr) {
 
 
 static grpc_channel *secure_test_create_channel(const char *addr) {
 static grpc_channel *secure_test_create_channel(const char *addr) {
   grpc_channel_credentials *ssl_creds =
   grpc_channel_credentials *ssl_creds =
-      grpc_ssl_credentials_create(NULL, NULL, NULL);
+      grpc_ssl_credentials_create(test_root_cert, NULL, NULL);
   grpc_arg ssl_name_override = {GRPC_ARG_STRING,
   grpc_arg ssl_name_override = {GRPC_ARG_STRING,
                                 GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
                                 GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
                                 {"foo.test.google.fr"}};
                                 {"foo.test.google.fr"}};