mirror of https://github.com/grpc/grpc.git
Conflicts: src/core/iomgr/resolve_address_posix.c src/core/surface/server.cpull/1731/head
commit
a4b89fed1c
155 changed files with 4326 additions and 4277 deletions
@ -0,0 +1,95 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015, Google Inc. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following disclaimer |
||||
* in the documentation and/or other materials provided with the |
||||
* distribution. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
*/ |
||||
|
||||
/* RPC-internal Census API's. These are designed to be generic enough that
|
||||
* they can (ultimately) be used in many different RPC systems (with differing |
||||
* implementations). */ |
||||
|
||||
#ifndef CENSUS_CENSUS_H |
||||
#define CENSUS_CENSUS_H |
||||
|
||||
#include <grpc/grpc.h> |
||||
|
||||
/* Identify census functionality that can be enabled via census_initialize(). */ |
||||
enum census_functions { |
||||
CENSUS_NONE = 0, /* Do not enable census. */ |
||||
CENSUS_TRACING = 1, /* Enable census tracing. */ |
||||
CENSUS_STATS = 2, /* Enable Census stats collection. */ |
||||
CENSUS_CPU = 4, /* Enable Census CPU usage collection. */ |
||||
CENSUS_ALL = CENSUS_TRACING | CENSUS_STATS | CENSUS_CPU |
||||
}; |
||||
|
||||
/* Shutdown and startup census subsystem. The 'functions' argument should be
|
||||
* the OR (|) of census_functions values. If census fails to initialize, then |
||||
* census_initialize() will return a non-zero value. It is an error to call |
||||
* census_initialize() more than once (without an intervening |
||||
* census_shutdown()). */ |
||||
int census_initialize(int functions); |
||||
void census_shutdown(); |
||||
|
||||
/* Internally, Census relies on a context, which should be propagated across
|
||||
* RPC's. From the RPC subsystems viewpoint, this is an opaque data structure. |
||||
* A context must be used as the first argument to all other census |
||||
* functions. Conceptually, contexts should be thought of as specific to |
||||
* single RPC/thread. The context can be serialized for passing across the |
||||
* wire. */ |
||||
typedef struct census_context census_context; |
||||
|
||||
/* This function is called by the RPC subsystem whenever it needs to get a
|
||||
* serialized form of the current census context (presumably to pass across |
||||
* the wire). Arguments: |
||||
* 'buffer': pointer to memory into which serialized context will be placed |
||||
* 'buf_size': size of 'buffer' |
||||
* |
||||
* Returns: the number of bytes used in buffer if successful, or 0 if the |
||||
* buffer is of insufficient size. |
||||
* |
||||
* TODO(aveitch): determine how best to communicate required/max buffer size |
||||
* so caller doesn't have to guess. */ |
||||
size_t census_context_serialize(const census_context *context, char *buffer, |
||||
size_t buf_size); |
||||
|
||||
/* Create a new census context, possibly from a serialized buffer. If 'buffer'
|
||||
* is non-NULL, it is assumed that it is a buffer encoded by |
||||
* census_context_serialize(). If `buffer` is NULL, a new, empty context is |
||||
* created. The decoded/new contest is returned in 'context'. |
||||
* |
||||
* Returns 0 if no errors, non-zero if buffer is incorrectly formatted, in |
||||
* which case a new empty context will be returned. */ |
||||
int census_context_deserialize(const char *buffer, census_context **context); |
||||
|
||||
/* The given context is destroyed. Once destroyed, using the context in
|
||||
* future census calls will result in undefined behavior. */ |
||||
void census_context_destroy(census_context *context); |
||||
|
||||
#endif /* CENSUS_CENSUS_H */ |
@ -1,41 +0,0 @@ |
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6214" systemVersion="14A314h" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES"> |
||||
<dependencies> |
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6207"/> |
||||
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/> |
||||
</dependencies> |
||||
<objects> |
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/> |
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> |
||||
<view contentMode="scaleToFill" id="iN0-l3-epB"> |
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/> |
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> |
||||
<subviews> |
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright (c) 2015 gRPC. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye"> |
||||
<rect key="frame" x="20" y="439" width="441" height="21"/> |
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/> |
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/> |
||||
<nil key="highlightedColor"/> |
||||
</label> |
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Sample" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX"> |
||||
<rect key="frame" x="20" y="140" width="441" height="43"/> |
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/> |
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/> |
||||
<nil key="highlightedColor"/> |
||||
</label> |
||||
</subviews> |
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/> |
||||
<constraints> |
||||
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/> |
||||
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/> |
||||
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/> |
||||
<constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/> |
||||
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/> |
||||
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/> |
||||
</constraints> |
||||
<nil key="simulatedStatusBarMetrics"/> |
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/> |
||||
<point key="canvasLocation" x="548" y="455"/> |
||||
</view> |
||||
</objects> |
||||
</document> |
@ -1,24 +0,0 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
||||
<plist version="1.0"> |
||||
<dict> |
||||
<key>CFBundleDevelopmentRegion</key> |
||||
<string>en</string> |
||||
<key>CFBundleExecutable</key> |
||||
<string>$(EXECUTABLE_NAME)</string> |
||||
<key>CFBundleIdentifier</key> |
||||
<string>org.grpc.$(PRODUCT_NAME:rfc1034identifier)</string> |
||||
<key>CFBundleInfoDictionaryVersion</key> |
||||
<string>6.0</string> |
||||
<key>CFBundleName</key> |
||||
<string>$(PRODUCT_NAME)</string> |
||||
<key>CFBundlePackageType</key> |
||||
<string>BNDL</string> |
||||
<key>CFBundleShortVersionString</key> |
||||
<string>1.0</string> |
||||
<key>CFBundleSignature</key> |
||||
<string>????</string> |
||||
<key>CFBundleVersion</key> |
||||
<string>1</string> |
||||
</dict> |
||||
</plist> |
@ -1,86 +0,0 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015, Google Inc. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following disclaimer |
||||
* in the documentation and/or other materials provided with the |
||||
* distribution. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
*/ |
||||
|
||||
#include <Python.h> |
||||
#include <grpc/grpc.h> |
||||
|
||||
#include "grpc/_adapter/_completion_queue.h" |
||||
#include "grpc/_adapter/_channel.h" |
||||
#include "grpc/_adapter/_call.h" |
||||
#include "grpc/_adapter/_server.h" |
||||
#include "grpc/_adapter/_client_credentials.h" |
||||
#include "grpc/_adapter/_server_credentials.h" |
||||
|
||||
static PyObject *init(PyObject *self) { |
||||
grpc_init(); |
||||
Py_RETURN_NONE; |
||||
} |
||||
|
||||
static PyObject *shutdown(PyObject *self) { |
||||
grpc_shutdown(); |
||||
Py_RETURN_NONE; |
||||
} |
||||
|
||||
static PyMethodDef _c_methods[] = { |
||||
{"init", (PyCFunction)init, METH_NOARGS, |
||||
"Initialize the module's static state."}, |
||||
{"shut_down", (PyCFunction)shutdown, METH_NOARGS, |
||||
"Shut down the module's static state."}, |
||||
{NULL}, |
||||
}; |
||||
|
||||
PyMODINIT_FUNC init_c(void) { |
||||
PyObject *module; |
||||
|
||||
module = Py_InitModule3("_c", _c_methods, |
||||
"Wrappings of C structures and functions."); |
||||
|
||||
if (pygrpc_add_completion_queue(module) == -1) { |
||||
return; |
||||
} |
||||
if (pygrpc_add_channel(module) == -1) { |
||||
return; |
||||
} |
||||
if (pygrpc_add_call(module) == -1) { |
||||
return; |
||||
} |
||||
if (pygrpc_add_server(module) == -1) { |
||||
return; |
||||
} |
||||
if (pygrpc_add_client_credentials(module) == -1) { |
||||
return; |
||||
} |
||||
if (pygrpc_add_server_credentials(module) == -1) { |
||||
return; |
||||
} |
||||
} |
@ -0,0 +1,61 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015, Google Inc. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following disclaimer |
||||
* in the documentation and/or other materials provided with the |
||||
* distribution. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
*/ |
||||
|
||||
#include <stdlib.h> |
||||
|
||||
#define PY_SSIZE_T_CLEAN |
||||
#include <Python.h> |
||||
#include <grpc/grpc.h> |
||||
|
||||
#include "grpc/_adapter/_c/types.h" |
||||
|
||||
static PyMethodDef c_methods[] = { |
||||
{NULL} |
||||
}; |
||||
|
||||
PyMODINIT_FUNC init_c(void) { |
||||
PyObject *module; |
||||
|
||||
module = Py_InitModule3("_c", c_methods, |
||||
"Wrappings of C structures and functions."); |
||||
|
||||
if (pygrpc_module_add_types(module) < 0) { |
||||
return; |
||||
} |
||||
|
||||
/* GRPC maintains an internal counter of how many times it has been
|
||||
initialized and handles multiple pairs of grpc_init()/grpc_shutdown() |
||||
invocations accordingly. */ |
||||
grpc_init(); |
||||
atexit(&grpc_shutdown); |
||||
} |
@ -0,0 +1,60 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015, Google Inc. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following disclaimer |
||||
* in the documentation and/or other materials provided with the |
||||
* distribution. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
*/ |
||||
|
||||
#include "grpc/_adapter/_c/types.h" |
||||
|
||||
#define PY_SSIZE_T_CLEAN |
||||
#include <Python.h> |
||||
#include <grpc/grpc.h> |
||||
|
||||
int pygrpc_module_add_types(PyObject *module) { |
||||
int i; |
||||
PyTypeObject *types[] = { |
||||
&pygrpc_ClientCredentials_type, |
||||
&pygrpc_ServerCredentials_type, |
||||
&pygrpc_CompletionQueue_type, |
||||
&pygrpc_Call_type, |
||||
&pygrpc_Channel_type, |
||||
&pygrpc_Server_type |
||||
}; |
||||
for (i = 0; i < sizeof(types)/sizeof(PyTypeObject *); ++i) { |
||||
if (PyType_Ready(types[i]) < 0) { |
||||
return -1; |
||||
} |
||||
} |
||||
for (i = 0; i < sizeof(types)/sizeof(PyTypeObject *); ++i) { |
||||
Py_INCREF(types[i]); |
||||
PyModule_AddObject(module, types[i]->tp_name, (PyObject *)types[i]); |
||||
} |
||||
return 0; |
||||
} |
@ -0,0 +1,271 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015, Google Inc. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following disclaimer |
||||
* in the documentation and/or other materials provided with the |
||||
* distribution. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC__ADAPTER__C_TYPES_H_ |
||||
#define GRPC__ADAPTER__C_TYPES_H_ |
||||
|
||||
#define PY_SSIZE_T_CLEAN |
||||
#include <Python.h> |
||||
#include <grpc/grpc.h> |
||||
#include <grpc/grpc_security.h> |
||||
|
||||
|
||||
/*=========================*/ |
||||
/* Client-side credentials */ |
||||
/*=========================*/ |
||||
|
||||
typedef struct ClientCredentials { |
||||
PyObject_HEAD |
||||
grpc_credentials *c_creds; |
||||
} ClientCredentials; |
||||
void pygrpc_ClientCredentials_dealloc(ClientCredentials *self); |
||||
ClientCredentials *pygrpc_ClientCredentials_google_default( |
||||
PyTypeObject *type, PyObject *ignored); |
||||
ClientCredentials *pygrpc_ClientCredentials_ssl( |
||||
PyTypeObject *type, PyObject *args, PyObject *kwargs); |
||||
ClientCredentials *pygrpc_ClientCredentials_composite( |
||||
PyTypeObject *type, PyObject *args, PyObject *kwargs); |
||||
ClientCredentials *pygrpc_ClientCredentials_compute_engine( |
||||
PyTypeObject *type, PyObject *ignored); |
||||
ClientCredentials *pygrpc_ClientCredentials_service_account( |
||||
PyTypeObject *type, PyObject *args, PyObject *kwargs); |
||||
ClientCredentials *pygrpc_ClientCredentials_jwt( |
||||
PyTypeObject *type, PyObject *args, PyObject *kwargs); |
||||
ClientCredentials *pygrpc_ClientCredentials_refresh_token( |
||||
PyTypeObject *type, PyObject *args, PyObject *kwargs); |
||||
ClientCredentials *pygrpc_ClientCredentials_fake_transport_security( |
||||
PyTypeObject *type, PyObject *ignored); |
||||
ClientCredentials *pygrpc_ClientCredentials_iam( |
||||
PyTypeObject *type, PyObject *args, PyObject *kwargs); |
||||
extern PyTypeObject pygrpc_ClientCredentials_type; |
||||
|
||||
|
||||
/*=========================*/ |
||||
/* Server-side credentials */ |
||||
/*=========================*/ |
||||
|
||||
typedef struct ServerCredentials { |
||||
PyObject_HEAD |
||||
grpc_server_credentials *c_creds; |
||||
} ServerCredentials; |
||||
void pygrpc_ServerCredentials_dealloc(ServerCredentials *self); |
||||
ServerCredentials *pygrpc_ServerCredentials_ssl( |
||||
PyTypeObject *type, PyObject *args, PyObject *kwargs); |
||||
ServerCredentials *pygrpc_ServerCredentials_fake_transport_security( |
||||
PyTypeObject *type, PyObject *ignored); |
||||
extern PyTypeObject pygrpc_ServerCredentials_type; |
||||
|
||||
|
||||
/*==================*/ |
||||
/* Completion queue */ |
||||
/*==================*/ |
||||
|
||||
typedef struct CompletionQueue { |
||||
PyObject_HEAD |
||||
grpc_completion_queue *c_cq; |
||||
} CompletionQueue; |
||||
CompletionQueue *pygrpc_CompletionQueue_new( |
||||
PyTypeObject *type, PyObject *args, PyObject *kwargs); |
||||
void pygrpc_CompletionQueue_dealloc(CompletionQueue *self); |
||||
PyObject *pygrpc_CompletionQueue_next( |
||||
CompletionQueue *self, PyObject *args, PyObject *kwargs); |
||||
PyObject *pygrpc_CompletionQueue_shutdown( |
||||
CompletionQueue *self, PyObject *ignored); |
||||
extern PyTypeObject pygrpc_CompletionQueue_type; |
||||
|
||||
|
||||
/*======*/ |
||||
/* Call */ |
||||
/*======*/ |
||||
|
||||
typedef struct Call { |
||||
PyObject_HEAD |
||||
grpc_call *c_call; |
||||
CompletionQueue *cq; |
||||
} Call; |
||||
Call *pygrpc_Call_new_empty(CompletionQueue *cq); |
||||
void pygrpc_Call_dealloc(Call *self); |
||||
PyObject *pygrpc_Call_start_batch(Call *self, PyObject *args, PyObject *kwargs); |
||||
PyObject *pygrpc_Call_cancel(Call *self, PyObject *args, PyObject *kwargs); |
||||
extern PyTypeObject pygrpc_Call_type; |
||||
|
||||
|
||||
/*=========*/ |
||||
/* Channel */ |
||||
/*=========*/ |
||||
|
||||
typedef struct Channel { |
||||
PyObject_HEAD |
||||
grpc_channel *c_chan; |
||||
} Channel; |
||||
Channel *pygrpc_Channel_new( |
||||
PyTypeObject *type, PyObject *args, PyObject *kwargs); |
||||
void pygrpc_Channel_dealloc(Channel *self); |
||||
Call *pygrpc_Channel_create_call( |
||||
Channel *self, PyObject *args, PyObject *kwargs); |
||||
extern PyTypeObject pygrpc_Channel_type; |
||||
|
||||
|
||||
/*========*/ |
||||
/* Server */ |
||||
/*========*/ |
||||
|
||||
typedef struct Server { |
||||
PyObject_HEAD |
||||
grpc_server *c_serv; |
||||
CompletionQueue *cq; |
||||
} Server; |
||||
Server *pygrpc_Server_new(PyTypeObject *type, PyObject *args, PyObject *kwargs); |
||||
void pygrpc_Server_dealloc(Server *self); |
||||
PyObject *pygrpc_Server_request_call( |
||||
Server *self, PyObject *args, PyObject *kwargs); |
||||
PyObject *pygrpc_Server_add_http2_port( |
||||
Server *self, PyObject *args, PyObject *kwargs); |
||||
PyObject *pygrpc_Server_start(Server *self, PyObject *ignored); |
||||
PyObject *pygrpc_Server_shutdown( |
||||
Server *self, PyObject *args, PyObject *kwargs); |
||||
extern PyTypeObject pygrpc_Server_type; |
||||
|
||||
/*=========*/ |
||||
/* Utility */ |
||||
/*=========*/ |
||||
|
||||
/* Every tag that passes from Python GRPC to GRPC core is of this type. */ |
||||
typedef struct pygrpc_tag { |
||||
PyObject *user_tag; |
||||
Call *call; |
||||
grpc_call_details request_call_details; |
||||
grpc_metadata_array request_metadata; |
||||
grpc_op *ops; |
||||
size_t nops; |
||||
int is_new_call; |
||||
} pygrpc_tag; |
||||
|
||||
/* Construct a tag associated with a batch call. Does not take ownership of the
|
||||
resources in the elements of ops. */ |
||||
pygrpc_tag *pygrpc_produce_batch_tag(PyObject *user_tag, Call *call, |
||||
grpc_op *ops, size_t nops); |
||||
|
||||
|
||||
/* Construct a tag associated with a server request. The calling code should
|
||||
use the appropriate fields of the produced tag in the invocation of |
||||
grpc_server_request_call. */ |
||||
pygrpc_tag *pygrpc_produce_request_tag(PyObject *user_tag, Call *empty_call); |
||||
|
||||
/* Construct a tag associated with a server shutdown. */ |
||||
pygrpc_tag *pygrpc_produce_server_shutdown_tag(PyObject *user_tag); |
||||
|
||||
/* Frees all resources owned by the tag and the tag itself. */ |
||||
void pygrpc_discard_tag(pygrpc_tag *tag); |
||||
|
||||
/* Consumes an event and its associated tag, providing a Python tuple of the
|
||||
form `(type, tag, call, call_details, results)` (where type is an integer |
||||
corresponding to a grpc_completion_type, tag is an arbitrary PyObject, call |
||||
is the call object associated with the event [if any], call_details is a |
||||
tuple of form `(method, host, deadline)` [if such details are available], |
||||
and resultd is a list of tuples of form `(type, metadata, message, status, |
||||
cancelled)` [where type corresponds to a grpc_op_type, metadata is a |
||||
sequence of 2-sequences of strings, message is a byte string, and status is |
||||
a 2-tuple of an integer corresponding to grpc_status_code and a string of |
||||
status details]). |
||||
|
||||
Frees all resources associated with the event tag. */ |
||||
PyObject *pygrpc_consume_event(grpc_event event); |
||||
|
||||
/* Transliterate the Python tuple of form `(type, metadata, message,
|
||||
status)` (where type is an integer corresponding to a grpc_op_type, metadata |
||||
is a sequence of 2-sequences of strings, message is a byte string, and |
||||
status is 2-tuple of an integer corresponding to grpc_status_code and a |
||||
string of status details) to a grpc_op suitable for use in a |
||||
grpc_call_start_batch invocation. The grpc_op is a 'directory' of resources |
||||
that must be freed after GRPC core is done with them. |
||||
|
||||
Calls gpr_malloc (or the appropriate type-specific grpc_*_create function) |
||||
to populate the appropriate union-discriminated members of the op. |
||||
|
||||
Returns true on success, false on failure. */ |
||||
int pygrpc_produce_op(PyObject *op, grpc_op *result); |
||||
|
||||
/* Discards all resources associated with the passed in op that was produced by
|
||||
pygrpc_produce_op. */ |
||||
void pygrpc_discard_op(grpc_op op); |
||||
|
||||
/* Transliterate the grpc_ops (which have been sent through a
|
||||
grpc_call_start_batch invocation and whose corresponding event has appeared |
||||
on a completion queue) to a Python tuple of form `(type, metadata, message, |
||||
status, cancelled)` (where type is an integer corresponding to a |
||||
grpc_op_type, metadata is a sequence of 2-sequences of strings, message is a |
||||
byte string, and status is 2-tuple of an integer corresponding to |
||||
grpc_status_code and a string of status details). |
||||
|
||||
Calls gpr_free (or the appropriate type-specific grpc_*_destroy function) on |
||||
the appropriate union-discriminated populated members of the ops. */ |
||||
PyObject *pygrpc_consume_ops(grpc_op *op, size_t nops); |
||||
|
||||
/* Transliterate from a gpr_timespec to a double (in units of seconds, either
|
||||
from the epoch if interpreted absolutely or as a delta otherwise). */ |
||||
double pygrpc_cast_gpr_timespec_to_double(gpr_timespec timespec); |
||||
|
||||
/* Transliterate from a double (in units of seconds from the epoch if
|
||||
interpreted absolutely or as a delta otherwise) to a gpr_timespec. */ |
||||
gpr_timespec pygrpc_cast_double_to_gpr_timespec(double seconds); |
||||
|
||||
/* Returns true on success, false on failure. */ |
||||
int pygrpc_cast_pylist_to_send_metadata( |
||||
PyObject *pylist, grpc_metadata **metadata, size_t *count); |
||||
/* Returns a metadata array as a Python object on success, else NULL. */ |
||||
PyObject *pygrpc_cast_metadata_array_to_pylist(grpc_metadata_array metadata); |
||||
|
||||
/* Transliterate from a list of python channel arguments (2-tuples of string
|
||||
and string|integer|None) to a grpc_channel_args object. The strings placed |
||||
in the grpc_channel_args object's grpc_arg elements are views of the Python |
||||
object. The Python object must live long enough for the grpc_channel_args |
||||
to be used. Arguments set to None are silently ignored. Returns true on |
||||
success, false on failure. */ |
||||
int pygrpc_produce_channel_args(PyObject *py_args, grpc_channel_args *c_args); |
||||
void pygrpc_discard_channel_args(grpc_channel_args args); |
||||
|
||||
/* Read the bytes from grpc_byte_buffer to a gpr_malloc'd array of bytes;
|
||||
output to result and result_size. */ |
||||
void pygrpc_byte_buffer_to_bytes( |
||||
grpc_byte_buffer *buffer, char **result, size_t *result_size); |
||||
|
||||
|
||||
/*========*/ |
||||
/* Module */ |
||||
/*========*/ |
||||
|
||||
/* Returns 0 on success, -1 on failure. */ |
||||
int pygrpc_module_add_types(PyObject *module); |
||||
|
||||
#endif /* GRPC__ADAPTER__C_TYPES_H_ */ |
@ -0,0 +1,163 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015, Google Inc. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following disclaimer |
||||
* in the documentation and/or other materials provided with the |
||||
* distribution. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
*/ |
||||
|
||||
#include "grpc/_adapter/_c/types.h" |
||||
|
||||
#define PY_SSIZE_T_CLEAN |
||||
#include <Python.h> |
||||
#include <grpc/grpc.h> |
||||
#include <grpc/support/alloc.h> |
||||
|
||||
|
||||
PyMethodDef pygrpc_Call_methods[] = { |
||||
{"start_batch", (PyCFunction)pygrpc_Call_start_batch, METH_KEYWORDS, ""}, |
||||
{"cancel", (PyCFunction)pygrpc_Call_cancel, METH_KEYWORDS, ""}, |
||||
{NULL} |
||||
}; |
||||
const char pygrpc_Call_doc[] = "See grpc._adapter._types.Call."; |
||||
PyTypeObject pygrpc_Call_type = { |
||||
PyObject_HEAD_INIT(NULL) |
||||
0, /* ob_size */ |
||||
"Call", /* tp_name */ |
||||
sizeof(Call), /* tp_basicsize */ |
||||
0, /* tp_itemsize */ |
||||
(destructor)pygrpc_Call_dealloc, /* tp_dealloc */ |
||||
0, /* tp_print */ |
||||
0, /* tp_getattr */ |
||||
0, /* tp_setattr */ |
||||
0, /* tp_compare */ |
||||
0, /* tp_repr */ |
||||
0, /* tp_as_number */ |
||||
0, /* tp_as_sequence */ |
||||
0, /* tp_as_mapping */ |
||||
0, /* tp_hash */ |
||||
0, /* tp_call */ |
||||
0, /* tp_str */ |
||||
0, /* tp_getattro */ |
||||
0, /* tp_setattro */ |
||||
0, /* tp_as_buffer */ |
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ |
||||
pygrpc_Call_doc, /* tp_doc */ |
||||
0, /* tp_traverse */ |
||||
0, /* tp_clear */ |
||||
0, /* tp_richcompare */ |
||||
0, /* tp_weaklistoffset */ |
||||
0, /* tp_iter */ |
||||
0, /* tp_iternext */ |
||||
pygrpc_Call_methods, /* tp_methods */ |
||||
0, /* tp_members */ |
||||
0, /* tp_getset */ |
||||
0, /* tp_base */ |
||||
0, /* tp_dict */ |
||||
0, /* tp_descr_get */ |
||||
0, /* tp_descr_set */ |
||||
0, /* tp_dictoffset */ |
||||
0, /* tp_init */ |
||||
0, /* tp_alloc */ |
||||
0 /* tp_new */ |
||||
}; |
||||
|
||||
Call *pygrpc_Call_new_empty(CompletionQueue *cq) { |
||||
Call *call = (Call *)pygrpc_Call_type.tp_alloc(&pygrpc_Call_type, 0); |
||||
call->c_call = NULL; |
||||
call->cq = cq; |
||||
Py_XINCREF(call->cq); |
||||
return call; |
||||
} |
||||
void pygrpc_Call_dealloc(Call *self) { |
||||
if (self->c_call) { |
||||
grpc_call_destroy(self->c_call); |
||||
} |
||||
Py_XDECREF(self->cq); |
||||
self->ob_type->tp_free((PyObject *)self); |
||||
} |
||||
PyObject *pygrpc_Call_start_batch(Call *self, PyObject *args, PyObject *kwargs) { |
||||
PyObject *op_list; |
||||
PyObject *user_tag; |
||||
grpc_op *ops; |
||||
size_t nops; |
||||
size_t i; |
||||
size_t j; |
||||
pygrpc_tag *tag; |
||||
grpc_call_error errcode; |
||||
static char *keywords[] = {"ops", "tag", NULL}; |
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO:start_batch", keywords, |
||||
&op_list, &user_tag)) { |
||||
return NULL; |
||||
} |
||||
if (!PyList_Check(op_list)) { |
||||
PyErr_SetString(PyExc_TypeError, "expected a list of OpArgs"); |
||||
return NULL; |
||||
} |
||||
nops = PyList_Size(op_list); |
||||
ops = gpr_malloc(sizeof(grpc_op) * nops); |
||||
for (i = 0; i < nops; ++i) { |
||||
PyObject *item = PyList_GET_ITEM(op_list, i); |
||||
if (!pygrpc_produce_op(item, &ops[i])) { |
||||
for (j = 0; j < i; ++j) { |
||||
pygrpc_discard_op(ops[j]); |
||||
} |
||||
return NULL; |
||||
} |
||||
} |
||||
tag = pygrpc_produce_batch_tag(user_tag, self, ops, nops); |
||||
errcode = grpc_call_start_batch(self->c_call, tag->ops, tag->nops, tag); |
||||
gpr_free(ops); |
||||
return PyInt_FromLong(errcode); |
||||
} |
||||
PyObject *pygrpc_Call_cancel(Call *self, PyObject *args, PyObject *kwargs) { |
||||
PyObject *py_code = NULL; |
||||
grpc_call_error errcode; |
||||
int code; |
||||
char *details = NULL; |
||||
static char *keywords[] = {"code", "details", NULL}; |
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Os:start_batch", keywords, |
||||
&py_code, &details)) { |
||||
return NULL; |
||||
} |
||||
if (py_code != NULL && details != NULL) { |
||||
if (!PyInt_Check(py_code)) { |
||||
PyErr_SetString(PyExc_TypeError, "expected integer code"); |
||||
return NULL; |
||||
} |
||||
code = PyInt_AsLong(py_code); |
||||
errcode = grpc_call_cancel_with_status(self->c_call, code, details); |
||||
} else if (py_code != NULL || details != NULL) { |
||||
PyErr_SetString(PyExc_ValueError, |
||||
"if `code` is specified, so must `details`"); |
||||
return NULL; |
||||
} else { |
||||
errcode = grpc_call_cancel(self->c_call); |
||||
} |
||||
return PyInt_FromLong(errcode); |
||||
} |
@ -0,0 +1,134 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015, Google Inc. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following disclaimer |
||||
* in the documentation and/or other materials provided with the |
||||
* distribution. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
*/ |
||||
|
||||
#include "grpc/_adapter/_c/types.h" |
||||
|
||||
#define PY_SSIZE_T_CLEAN |
||||
#include <Python.h> |
||||
#include <grpc/grpc.h> |
||||
|
||||
|
||||
PyMethodDef pygrpc_Channel_methods[] = { |
||||
{"create_call", (PyCFunction)pygrpc_Channel_create_call, METH_KEYWORDS, ""}, |
||||
{NULL} |
||||
}; |
||||
const char pygrpc_Channel_doc[] = "See grpc._adapter._types.Channel."; |
||||
PyTypeObject pygrpc_Channel_type = { |
||||
PyObject_HEAD_INIT(NULL) |
||||
0, /* ob_size */ |
||||
"Channel", /* tp_name */ |
||||
sizeof(Channel), /* tp_basicsize */ |
||||
0, /* tp_itemsize */ |
||||
(destructor)pygrpc_Channel_dealloc, /* tp_dealloc */ |
||||
0, /* tp_print */ |
||||
0, /* tp_getattr */ |
||||
0, /* tp_setattr */ |
||||
0, /* tp_compare */ |
||||
0, /* tp_repr */ |
||||
0, /* tp_as_number */ |
||||
0, /* tp_as_sequence */ |
||||
0, /* tp_as_mapping */ |
||||
0, /* tp_hash */ |
||||
0, /* tp_call */ |
||||
0, /* tp_str */ |
||||
0, /* tp_getattro */ |
||||
0, /* tp_setattro */ |
||||
0, /* tp_as_buffer */ |
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ |
||||
pygrpc_Channel_doc, /* tp_doc */ |
||||
0, /* tp_traverse */ |
||||
0, /* tp_clear */ |
||||
0, /* tp_richcompare */ |
||||
0, /* tp_weaklistoffset */ |
||||
0, /* tp_iter */ |
||||
0, /* tp_iternext */ |
||||
pygrpc_Channel_methods, /* tp_methods */ |
||||
0, /* tp_members */ |
||||
0, /* tp_getset */ |
||||
0, /* tp_base */ |
||||
0, /* tp_dict */ |
||||
0, /* tp_descr_get */ |
||||
0, /* tp_descr_set */ |
||||
0, /* tp_dictoffset */ |
||||
0, /* tp_init */ |
||||
0, /* tp_alloc */ |
||||
(newfunc)pygrpc_Channel_new /* tp_new */ |
||||
}; |
||||
|
||||
Channel *pygrpc_Channel_new( |
||||
PyTypeObject *type, PyObject *args, PyObject *kwargs) { |
||||
Channel *self; |
||||
const char *target; |
||||
PyObject *py_args; |
||||
ClientCredentials *creds = NULL; |
||||
grpc_channel_args c_args; |
||||
char *keywords[] = {"target", "args", "creds", NULL}; |
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO|O!:Channel", keywords, |
||||
&target, &py_args, &pygrpc_ClientCredentials_type, &creds)) { |
||||
return NULL; |
||||
} |
||||
if (!pygrpc_produce_channel_args(py_args, &c_args)) { |
||||
return NULL; |
||||
} |
||||
self = (Channel *)type->tp_alloc(type, 0); |
||||
if (creds) { |
||||
self->c_chan = grpc_secure_channel_create(creds->c_creds, target, &c_args); |
||||
} else { |
||||
self->c_chan = grpc_channel_create(target, &c_args); |
||||
} |
||||
pygrpc_discard_channel_args(c_args); |
||||
return self; |
||||
} |
||||
void pygrpc_Channel_dealloc(Channel *self) { |
||||
grpc_channel_destroy(self->c_chan); |
||||
self->ob_type->tp_free((PyObject *)self); |
||||
} |
||||
|
||||
Call *pygrpc_Channel_create_call( |
||||
Channel *self, PyObject *args, PyObject *kwargs) { |
||||
Call *call; |
||||
CompletionQueue *cq; |
||||
const char *method; |
||||
const char *host; |
||||
double deadline; |
||||
char *keywords[] = {"cq", "method", "host", "deadline", NULL}; |
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!ssd:create_call", keywords, |
||||
&pygrpc_CompletionQueue_type, &cq, &method, &host, &deadline)) { |
||||
return NULL; |
||||
} |
||||
call = pygrpc_Call_new_empty(cq); |
||||
call->c_call = grpc_channel_create_call( |
||||
self->c_chan, cq->c_cq, method, host, |
||||
pygrpc_cast_double_to_gpr_timespec(deadline)); |
||||
return call; |
||||
} |
@ -0,0 +1,286 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015, Google Inc. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following disclaimer |
||||
* in the documentation and/or other materials provided with the |
||||
* distribution. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
*/ |
||||
|
||||
#include "grpc/_adapter/_c/types.h" |
||||
|
||||
#define PY_SSIZE_T_CLEAN |
||||
#include <Python.h> |
||||
#include <grpc/grpc.h> |
||||
#include <grpc/grpc_security.h> |
||||
|
||||
|
||||
PyMethodDef pygrpc_ClientCredentials_methods[] = { |
||||
{"google_default", (PyCFunction)pygrpc_ClientCredentials_google_default, |
||||
METH_CLASS|METH_NOARGS, ""}, |
||||
{"ssl", (PyCFunction)pygrpc_ClientCredentials_ssl, |
||||
METH_CLASS|METH_KEYWORDS, ""}, |
||||
{"composite", (PyCFunction)pygrpc_ClientCredentials_composite, |
||||
METH_CLASS|METH_KEYWORDS, ""}, |
||||
{"compute_engine", (PyCFunction)pygrpc_ClientCredentials_compute_engine, |
||||
METH_CLASS|METH_NOARGS, ""}, |
||||
{"service_account", (PyCFunction)pygrpc_ClientCredentials_service_account, |
||||
METH_CLASS|METH_KEYWORDS, ""}, |
||||
{"jwt", (PyCFunction)pygrpc_ClientCredentials_jwt, |
||||
METH_CLASS|METH_KEYWORDS, ""}, |
||||
{"refresh_token", (PyCFunction)pygrpc_ClientCredentials_refresh_token, |
||||
METH_CLASS|METH_KEYWORDS, ""}, |
||||
{"fake_transport_security", |
||||
(PyCFunction)pygrpc_ClientCredentials_fake_transport_security, |
||||
METH_CLASS|METH_NOARGS, ""}, |
||||
{"iam", (PyCFunction)pygrpc_ClientCredentials_iam, |
||||
METH_CLASS|METH_KEYWORDS, ""}, |
||||
{NULL} |
||||
}; |
||||
const char pygrpc_ClientCredentials_doc[] = ""; |
||||
PyTypeObject pygrpc_ClientCredentials_type = { |
||||
PyObject_HEAD_INIT(NULL) |
||||
0, /* ob_size */ |
||||
"ClientCredentials", /* tp_name */ |
||||
sizeof(ClientCredentials), /* tp_basicsize */ |
||||
0, /* tp_itemsize */ |
||||
(destructor)pygrpc_ClientCredentials_dealloc, /* tp_dealloc */ |
||||
0, /* tp_print */ |
||||
0, /* tp_getattr */ |
||||
0, /* tp_setattr */ |
||||
0, /* tp_compare */ |
||||
0, /* tp_repr */ |
||||
0, /* tp_as_number */ |
||||
0, /* tp_as_sequence */ |
||||
0, /* tp_as_mapping */ |
||||
0, /* tp_hash */ |
||||
0, /* tp_call */ |
||||
0, /* tp_str */ |
||||
0, /* tp_getattro */ |
||||
0, /* tp_setattro */ |
||||
0, /* tp_as_buffer */ |
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ |
||||
pygrpc_ClientCredentials_doc, /* tp_doc */ |
||||
0, /* tp_traverse */ |
||||
0, /* tp_clear */ |
||||
0, /* tp_richcompare */ |
||||
0, /* tp_weaklistoffset */ |
||||
0, /* tp_iter */ |
||||
0, /* tp_iternext */ |
||||
pygrpc_ClientCredentials_methods, /* tp_methods */ |
||||
0, /* tp_members */ |
||||
0, /* tp_getset */ |
||||
0, /* tp_base */ |
||||
0, /* tp_dict */ |
||||
0, /* tp_descr_get */ |
||||
0, /* tp_descr_set */ |
||||
0, /* tp_dictoffset */ |
||||
0, /* tp_init */ |
||||
0, /* tp_alloc */ |
||||
0 /* tp_new */ |
||||
}; |
||||
|
||||
void pygrpc_ClientCredentials_dealloc(ClientCredentials *self) { |
||||
grpc_credentials_release(self->c_creds); |
||||
self->ob_type->tp_free((PyObject *)self); |
||||
} |
||||
|
||||
ClientCredentials *pygrpc_ClientCredentials_google_default( |
||||
PyTypeObject *type, PyObject *ignored) { |
||||
ClientCredentials *self = (ClientCredentials *)type->tp_alloc(type, 0); |
||||
self->c_creds = grpc_google_default_credentials_create(); |
||||
if (!self->c_creds) { |
||||
Py_DECREF(self); |
||||
PyErr_SetString(PyExc_RuntimeError, |
||||
"couldn't create Google default credentials"); |
||||
return NULL; |
||||
} |
||||
return self; |
||||
} |
||||
|
||||
ClientCredentials *pygrpc_ClientCredentials_ssl( |
||||
PyTypeObject *type, PyObject *args, PyObject *kwargs) { |
||||
ClientCredentials *self; |
||||
const char *root_certs; |
||||
const char *private_key = NULL; |
||||
const char *cert_chain = NULL; |
||||
grpc_ssl_pem_key_cert_pair key_cert_pair; |
||||
static char *keywords[] = {"root_certs", "private_key", "cert_chain", NULL}; |
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|zz:ssl", keywords, |
||||
&root_certs, &private_key, &cert_chain)) { |
||||
return NULL; |
||||
} |
||||
self = (ClientCredentials *)type->tp_alloc(type, 0); |
||||
if (private_key && cert_chain) { |
||||
key_cert_pair.private_key = private_key; |
||||
key_cert_pair.cert_chain = cert_chain; |
||||
self->c_creds = grpc_ssl_credentials_create(root_certs, &key_cert_pair); |
||||
} else { |
||||
self->c_creds = grpc_ssl_credentials_create(root_certs, NULL); |
||||
} |
||||
if (!self->c_creds) { |
||||
Py_DECREF(self); |
||||
PyErr_SetString(PyExc_RuntimeError, "couldn't create ssl credentials"); |
||||
return NULL; |
||||
} |
||||
return self; |
||||
} |
||||
|
||||
ClientCredentials *pygrpc_ClientCredentials_composite( |
||||
PyTypeObject *type, PyObject *args, PyObject *kwargs) { |
||||
ClientCredentials *self; |
||||
ClientCredentials *creds1; |
||||
ClientCredentials *creds2; |
||||
static char *keywords[] = {"creds1", "creds2", NULL}; |
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O!:composite", keywords, |
||||
&pygrpc_ClientCredentials_type, &creds1, |
||||
&pygrpc_ClientCredentials_type, &creds2)) { |
||||
return NULL; |
||||
} |
||||
self = (ClientCredentials *)type->tp_alloc(type, 0); |
||||
self->c_creds = grpc_composite_credentials_create( |
||||
creds1->c_creds, creds2->c_creds); |
||||
if (!self->c_creds) { |
||||
Py_DECREF(self); |
||||
PyErr_SetString(PyExc_RuntimeError, "couldn't create composite credentials"); |
||||
return NULL; |
||||
} |
||||
return self; |
||||
} |
||||
|
||||
ClientCredentials *pygrpc_ClientCredentials_compute_engine( |
||||
PyTypeObject *type, PyObject *ignored) { |
||||
ClientCredentials *self = (ClientCredentials *)type->tp_alloc(type, 0); |
||||
self->c_creds = grpc_compute_engine_credentials_create(); |
||||
if (!self->c_creds) { |
||||
Py_DECREF(self); |
||||
PyErr_SetString(PyExc_RuntimeError, |
||||
"couldn't create compute engine credentials"); |
||||
return NULL; |
||||
} |
||||
return self; |
||||
} |
||||
|
||||
ClientCredentials *pygrpc_ClientCredentials_service_account( |
||||
PyTypeObject *type, PyObject *args, PyObject *kwargs) { |
||||
ClientCredentials *self; |
||||
const char *json_key; |
||||
const char *scope; |
||||
double lifetime; |
||||
static char *keywords[] = {"json_key", "scope", "token_lifetime", NULL}; |
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ssd:service_account", keywords, |
||||
&json_key, &scope, &lifetime)) { |
||||
return NULL; |
||||
} |
||||
self = (ClientCredentials *)type->tp_alloc(type, 0); |
||||
self->c_creds = grpc_service_account_credentials_create( |
||||
json_key, scope, pygrpc_cast_double_to_gpr_timespec(lifetime)); |
||||
if (!self->c_creds) { |
||||
Py_DECREF(self); |
||||
PyErr_SetString(PyExc_RuntimeError, |
||||
"couldn't create service account credentials"); |
||||
return NULL; |
||||
} |
||||
return self; |
||||
} |
||||
|
||||
ClientCredentials *pygrpc_ClientCredentials_jwt( |
||||
PyTypeObject *type, PyObject *args, PyObject *kwargs) { |
||||
ClientCredentials *self; |
||||
const char *json_key; |
||||
double lifetime; |
||||
static char *keywords[] = {"json_key", "token_lifetime", NULL}; |
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sd:jwt", keywords, |
||||
&json_key, &lifetime)) { |
||||
return NULL; |
||||
} |
||||
self = (ClientCredentials *)type->tp_alloc(type, 0); |
||||
self->c_creds = grpc_jwt_credentials_create( |
||||
json_key, pygrpc_cast_double_to_gpr_timespec(lifetime)); |
||||
if (!self->c_creds) { |
||||
Py_DECREF(self); |
||||
PyErr_SetString(PyExc_RuntimeError, "couldn't create JWT credentials"); |
||||
return NULL; |
||||
} |
||||
return self; |
||||
} |
||||
|
||||
ClientCredentials *pygrpc_ClientCredentials_refresh_token( |
||||
PyTypeObject *type, PyObject *args, PyObject *kwargs) { |
||||
ClientCredentials *self; |
||||
const char *json_refresh_token; |
||||
static char *keywords[] = {"json_refresh_token", NULL}; |
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s:refresh_token", keywords, |
||||
&json_refresh_token)) { |
||||
return NULL; |
||||
} |
||||
self = (ClientCredentials *)type->tp_alloc(type, 0); |
||||
self->c_creds = grpc_refresh_token_credentials_create(json_refresh_token); |
||||
if (!self->c_creds) { |
||||
Py_DECREF(self); |
||||
PyErr_SetString(PyExc_RuntimeError, |
||||
"couldn't create credentials from refresh token"); |
||||
return NULL; |
||||
} |
||||
return self; |
||||
} |
||||
|
||||
ClientCredentials *pygrpc_ClientCredentials_fake_transport_security( |
||||
PyTypeObject *type, PyObject *ignored) { |
||||
ClientCredentials *self = (ClientCredentials *)type->tp_alloc(type, 0); |
||||
self->c_creds = grpc_fake_transport_security_credentials_create(); |
||||
if (!self->c_creds) { |
||||
Py_DECREF(self); |
||||
PyErr_SetString(PyExc_RuntimeError, |
||||
"couldn't create fake credentials; " |
||||
"something is horribly wrong with the universe"); |
||||
return NULL; |
||||
} |
||||
return self; |
||||
} |
||||
|
||||
ClientCredentials *pygrpc_ClientCredentials_iam( |
||||
PyTypeObject *type, PyObject *args, PyObject *kwargs) { |
||||
ClientCredentials *self; |
||||
const char *authorization_token; |
||||
const char *authority_selector; |
||||
static char *keywords[] = {"authorization_token", "authority_selector", NULL}; |
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ss:iam", keywords, |
||||
&authorization_token, &authority_selector)) { |
||||
return NULL; |
||||
} |
||||
self = (ClientCredentials *)type->tp_alloc(type, 0); |
||||
self->c_creds = grpc_iam_credentials_create(authorization_token, |
||||
authority_selector); |
||||
if (!self->c_creds) { |
||||
Py_DECREF(self); |
||||
PyErr_SetString(PyExc_RuntimeError, "couldn't create IAM credentials"); |
||||
return NULL; |
||||
} |
||||
return self; |
||||
} |
||||
|
@ -0,0 +1,124 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015, Google Inc. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following disclaimer |
||||
* in the documentation and/or other materials provided with the |
||||
* distribution. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
*/ |
||||
|
||||
#include "grpc/_adapter/_c/types.h" |
||||
|
||||
#define PY_SSIZE_T_CLEAN |
||||
#include <Python.h> |
||||
#include <grpc/grpc.h> |
||||
|
||||
|
||||
PyMethodDef pygrpc_CompletionQueue_methods[] = { |
||||
{"next", (PyCFunction)pygrpc_CompletionQueue_next, METH_KEYWORDS, ""}, |
||||
{"shutdown", (PyCFunction)pygrpc_CompletionQueue_shutdown, METH_NOARGS, ""}, |
||||
{NULL} |
||||
}; |
||||
const char pygrpc_CompletionQueue_doc[] = |
||||
"See grpc._adapter._types.CompletionQueue."; |
||||
PyTypeObject pygrpc_CompletionQueue_type = { |
||||
PyObject_HEAD_INIT(NULL) |
||||
0, /* ob_size */ |
||||
"CompletionQueue", /* tp_name */ |
||||
sizeof(CompletionQueue), /* tp_basicsize */ |
||||
0, /* tp_itemsize */ |
||||
(destructor)pygrpc_CompletionQueue_dealloc, /* tp_dealloc */ |
||||
0, /* tp_print */ |
||||
0, /* tp_getattr */ |
||||
0, /* tp_setattr */ |
||||
0, /* tp_compare */ |
||||
0, /* tp_repr */ |
||||
0, /* tp_as_number */ |
||||
0, /* tp_as_sequence */ |
||||
0, /* tp_as_mapping */ |
||||
0, /* tp_hash */ |
||||
0, /* tp_call */ |
||||
0, /* tp_str */ |
||||
0, /* tp_getattro */ |
||||
0, /* tp_setattro */ |
||||
0, /* tp_as_buffer */ |
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ |
||||
pygrpc_CompletionQueue_doc, /* tp_doc */ |
||||
0, /* tp_traverse */ |
||||
0, /* tp_clear */ |
||||
0, /* tp_richcompare */ |
||||
0, /* tp_weaklistoffset */ |
||||
0, /* tp_iter */ |
||||
0, /* tp_iternext */ |
||||
pygrpc_CompletionQueue_methods, /* tp_methods */ |
||||
0, /* tp_members */ |
||||
0, /* tp_getset */ |
||||
0, /* tp_base */ |
||||
0, /* tp_dict */ |
||||
0, /* tp_descr_get */ |
||||
0, /* tp_descr_set */ |
||||
0, /* tp_dictoffset */ |
||||
0, /* tp_init */ |
||||
0, /* tp_alloc */ |
||||
(newfunc)pygrpc_CompletionQueue_new /* tp_new */ |
||||
}; |
||||
|
||||
CompletionQueue *pygrpc_CompletionQueue_new( |
||||
PyTypeObject *type, PyObject *args, PyObject *kwargs) { |
||||
CompletionQueue *self = (CompletionQueue *)type->tp_alloc(type, 0); |
||||
self->c_cq = grpc_completion_queue_create(); |
||||
return self; |
||||
} |
||||
|
||||
void pygrpc_CompletionQueue_dealloc(CompletionQueue *self) { |
||||
grpc_completion_queue_destroy(self->c_cq); |
||||
self->ob_type->tp_free((PyObject *)self); |
||||
} |
||||
|
||||
PyObject *pygrpc_CompletionQueue_next( |
||||
CompletionQueue *self, PyObject *args, PyObject *kwargs) { |
||||
double deadline; |
||||
grpc_event event; |
||||
PyObject *transliterated_event; |
||||
static char *keywords[] = {"deadline", NULL}; |
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "d:next", keywords, |
||||
&deadline)) { |
||||
return NULL; |
||||
} |
||||
Py_BEGIN_ALLOW_THREADS; |
||||
event = grpc_completion_queue_next( |
||||
self->c_cq, pygrpc_cast_double_to_gpr_timespec(deadline)); |
||||
Py_END_ALLOW_THREADS; |
||||
transliterated_event = pygrpc_consume_event(event); |
||||
return transliterated_event; |
||||
} |
||||
|
||||
PyObject *pygrpc_CompletionQueue_shutdown( |
||||
CompletionQueue *self, PyObject *ignored) { |
||||
grpc_completion_queue_shutdown(self->c_cq); |
||||
Py_RETURN_NONE; |
||||
} |
@ -0,0 +1,183 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015, Google Inc. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following disclaimer |
||||
* in the documentation and/or other materials provided with the |
||||
* distribution. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
*/ |
||||
|
||||
#include "grpc/_adapter/_c/types.h" |
||||
|
||||
#define PY_SSIZE_T_CLEAN |
||||
#include <Python.h> |
||||
#include <grpc/grpc.h> |
||||
|
||||
|
||||
PyMethodDef pygrpc_Server_methods[] = { |
||||
{"request_call", (PyCFunction)pygrpc_Server_request_call, |
||||
METH_KEYWORDS, ""}, |
||||
{"add_http2_port", (PyCFunction)pygrpc_Server_add_http2_port, |
||||
METH_KEYWORDS, ""}, |
||||
{"start", (PyCFunction)pygrpc_Server_start, METH_NOARGS, ""}, |
||||
{"shutdown", (PyCFunction)pygrpc_Server_shutdown, METH_KEYWORDS, ""}, |
||||
{NULL} |
||||
}; |
||||
const char pygrpc_Server_doc[] = "See grpc._adapter._types.Server."; |
||||
PyTypeObject pygrpc_Server_type = { |
||||
PyObject_HEAD_INIT(NULL) |
||||
0, /* ob_size */ |
||||
"Server", /* tp_name */ |
||||
sizeof(Server), /* tp_basicsize */ |
||||
0, /* tp_itemsize */ |
||||
(destructor)pygrpc_Server_dealloc, /* tp_dealloc */ |
||||
0, /* tp_print */ |
||||
0, /* tp_getattr */ |
||||
0, /* tp_setattr */ |
||||
0, /* tp_compare */ |
||||
0, /* tp_repr */ |
||||
0, /* tp_as_number */ |
||||
0, /* tp_as_sequence */ |
||||
0, /* tp_as_mapping */ |
||||
0, /* tp_hash */ |
||||
0, /* tp_call */ |
||||
0, /* tp_str */ |
||||
0, /* tp_getattro */ |
||||
0, /* tp_setattro */ |
||||
0, /* tp_as_buffer */ |
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ |
||||
pygrpc_Server_doc, /* tp_doc */ |
||||
0, /* tp_traverse */ |
||||
0, /* tp_clear */ |
||||
0, /* tp_richcompare */ |
||||
0, /* tp_weaklistoffset */ |
||||
0, /* tp_iter */ |
||||
0, /* tp_iternext */ |
||||
pygrpc_Server_methods, /* tp_methods */ |
||||
0, /* tp_members */ |
||||
0, /* tp_getset */ |
||||
0, /* tp_base */ |
||||
0, /* tp_dict */ |
||||
0, /* tp_descr_get */ |
||||
0, /* tp_descr_set */ |
||||
0, /* tp_dictoffset */ |
||||
0, /* tp_init */ |
||||
0, /* tp_alloc */ |
||||
(newfunc)pygrpc_Server_new /* tp_new */ |
||||
}; |
||||
|
||||
Server *pygrpc_Server_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { |
||||
Server *self; |
||||
CompletionQueue *cq; |
||||
PyObject *py_args; |
||||
grpc_channel_args c_args; |
||||
char *keywords[] = {"cq", "args", NULL}; |
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O:Channel", keywords, |
||||
&pygrpc_CompletionQueue_type, &cq, &py_args)) { |
||||
return NULL; |
||||
} |
||||
if (!pygrpc_produce_channel_args(py_args, &c_args)) { |
||||
return NULL; |
||||
} |
||||
self = (Server *)type->tp_alloc(type, 0); |
||||
self->c_serv = grpc_server_create(&c_args); |
||||
pygrpc_discard_channel_args(c_args); |
||||
self->cq = cq; |
||||
Py_INCREF(self->cq); |
||||
return self; |
||||
} |
||||
|
||||
void pygrpc_Server_dealloc(Server *self) { |
||||
grpc_server_destroy(self->c_serv); |
||||
Py_XDECREF(self->cq); |
||||
self->ob_type->tp_free((PyObject *)self); |
||||
} |
||||
|
||||
PyObject *pygrpc_Server_request_call( |
||||
Server *self, PyObject *args, PyObject *kwargs) { |
||||
CompletionQueue *cq; |
||||
PyObject *user_tag; |
||||
pygrpc_tag *tag; |
||||
Call *empty_call; |
||||
grpc_call_error errcode; |
||||
static char *keywords[] = {"cq", "tag", NULL}; |
||||
if (!PyArg_ParseTupleAndKeywords( |
||||
args, kwargs, "O!O", keywords, |
||||
&pygrpc_CompletionQueue_type, &cq, &user_tag)) { |
||||
return NULL; |
||||
} |
||||
empty_call = pygrpc_Call_new_empty(cq); |
||||
tag = pygrpc_produce_request_tag(user_tag, empty_call); |
||||
errcode = grpc_server_request_call( |
||||
self->c_serv, &tag->call->c_call, &tag->request_call_details, |
||||
&tag->request_metadata, tag->call->cq->c_cq, self->cq->c_cq, tag); |
||||
Py_DECREF(empty_call); |
||||
return PyInt_FromLong(errcode); |
||||
} |
||||
|
||||
PyObject *pygrpc_Server_add_http2_port( |
||||
Server *self, PyObject *args, PyObject *kwargs) { |
||||
const char *addr; |
||||
ServerCredentials *creds = NULL; |
||||
int port; |
||||
static char *keywords[] = {"addr", "creds", NULL}; |
||||
if (!PyArg_ParseTupleAndKeywords( |
||||
args, kwargs, "s|O!:add_http2_port", keywords, |
||||
&addr, &pygrpc_ServerCredentials_type, &creds)) { |
||||
return NULL; |
||||
} |
||||
if (creds) { |
||||
port = grpc_server_add_secure_http2_port( |
||||
self->c_serv, addr, creds->c_creds); |
||||
} else { |
||||
port = grpc_server_add_http2_port(self->c_serv, addr); |
||||
} |
||||
return PyInt_FromLong(port); |
||||
|
||||
} |
||||
|
||||
PyObject *pygrpc_Server_start(Server *self, PyObject *ignored) { |
||||
grpc_server_start(self->c_serv); |
||||
Py_RETURN_NONE; |
||||
} |
||||
|
||||
PyObject *pygrpc_Server_shutdown( |
||||
Server *self, PyObject *args, PyObject *kwargs) { |
||||
PyObject *user_tag = NULL; |
||||
pygrpc_tag *tag; |
||||
static char *keywords[] = {"tag", NULL}; |
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", keywords, &user_tag)) { |
||||
return NULL; |
||||
} |
||||
if (user_tag) { |
||||
tag = pygrpc_produce_server_shutdown_tag(user_tag); |
||||
grpc_server_shutdown_and_notify(self->c_serv, tag); |
||||
} else { |
||||
grpc_server_shutdown(self->c_serv); |
||||
} |
||||
Py_RETURN_NONE; |
||||
} |
@ -0,0 +1,146 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015, Google Inc. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following disclaimer |
||||
* in the documentation and/or other materials provided with the |
||||
* distribution. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
*/ |
||||
|
||||
#include "grpc/_adapter/_c/types.h" |
||||
|
||||
#define PY_SSIZE_T_CLEAN |
||||
#include <Python.h> |
||||
#include <grpc/grpc.h> |
||||
#include <grpc/grpc_security.h> |
||||
#include <grpc/support/alloc.h> |
||||
|
||||
|
||||
PyMethodDef pygrpc_ServerCredentials_methods[] = { |
||||
{"ssl", (PyCFunction)pygrpc_ServerCredentials_ssl, |
||||
METH_CLASS|METH_KEYWORDS, ""}, |
||||
{"fake_transport_security", |
||||
(PyCFunction)pygrpc_ServerCredentials_fake_transport_security, |
||||
METH_CLASS|METH_NOARGS, ""}, |
||||
{NULL} |
||||
}; |
||||
const char pygrpc_ServerCredentials_doc[] = ""; |
||||
PyTypeObject pygrpc_ServerCredentials_type = { |
||||
PyObject_HEAD_INIT(NULL) |
||||
0, /* ob_size */ |
||||
"ServerCredentials", /* tp_name */ |
||||
sizeof(ServerCredentials), /* tp_basicsize */ |
||||
0, /* tp_itemsize */ |
||||
(destructor)pygrpc_ServerCredentials_dealloc, /* tp_dealloc */ |
||||
0, /* tp_print */ |
||||
0, /* tp_getattr */ |
||||
0, /* tp_setattr */ |
||||
0, /* tp_compare */ |
||||
0, /* tp_repr */ |
||||
0, /* tp_as_number */ |
||||
0, /* tp_as_sequence */ |
||||
0, /* tp_as_mapping */ |
||||
0, /* tp_hash */ |
||||
0, /* tp_call */ |
||||
0, /* tp_str */ |
||||
0, /* tp_getattro */ |
||||
0, /* tp_setattro */ |
||||
0, /* tp_as_buffer */ |
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ |
||||
pygrpc_ServerCredentials_doc, /* tp_doc */ |
||||
0, /* tp_traverse */ |
||||
0, /* tp_clear */ |
||||
0, /* tp_richcompare */ |
||||
0, /* tp_weaklistoffset */ |
||||
0, /* tp_iter */ |
||||
0, /* tp_iternext */ |
||||
pygrpc_ServerCredentials_methods, /* tp_methods */ |
||||
0, /* tp_members */ |
||||
0, /* tp_getset */ |
||||
0, /* tp_base */ |
||||
0, /* tp_dict */ |
||||
0, /* tp_descr_get */ |
||||
0, /* tp_descr_set */ |
||||
0, /* tp_dictoffset */ |
||||
0, /* tp_init */ |
||||
0, /* tp_alloc */ |
||||
0 /* tp_new */ |
||||
}; |
||||
|
||||
void pygrpc_ServerCredentials_dealloc(ServerCredentials *self) { |
||||
grpc_server_credentials_release(self->c_creds); |
||||
self->ob_type->tp_free((PyObject *)self); |
||||
} |
||||
|
||||
ServerCredentials *pygrpc_ServerCredentials_ssl( |
||||
PyTypeObject *type, PyObject *args, PyObject *kwargs) { |
||||
ServerCredentials *self; |
||||
const char *root_certs; |
||||
PyObject *py_key_cert_pairs; |
||||
grpc_ssl_pem_key_cert_pair *key_cert_pairs; |
||||
size_t num_key_cert_pairs; |
||||
size_t i; |
||||
static char *keywords[] = {"root_certs", "key_cert_pairs", NULL}; |
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "zO:ssl", keywords, |
||||
&root_certs, &py_key_cert_pairs)) { |
||||
return NULL; |
||||
} |
||||
if (!PyList_Check(py_key_cert_pairs)) { |
||||
PyErr_SetString(PyExc_TypeError, "expected a list of 2-tuples of strings"); |
||||
return NULL; |
||||
} |
||||
num_key_cert_pairs = PyList_Size(py_key_cert_pairs); |
||||
key_cert_pairs = |
||||
gpr_malloc(sizeof(grpc_ssl_pem_key_cert_pair) * num_key_cert_pairs); |
||||
for (i = 0; i < num_key_cert_pairs; ++i) { |
||||
PyObject *item = PyList_GET_ITEM(py_key_cert_pairs, i); |
||||
const char *key; |
||||
const char *cert; |
||||
if (!PyArg_ParseTuple(item, "zz", &key, &cert)) { |
||||
gpr_free(key_cert_pairs); |
||||
PyErr_SetString(PyExc_TypeError, |
||||
"expected a list of 2-tuples of strings"); |
||||
return NULL; |
||||
} |
||||
key_cert_pairs[i].private_key = key; |
||||
key_cert_pairs[i].cert_chain = cert; |
||||
} |
||||
|
||||
self = (ServerCredentials *)type->tp_alloc(type, 0); |
||||
self->c_creds = grpc_ssl_server_credentials_create( |
||||
root_certs, key_cert_pairs, num_key_cert_pairs); |
||||
gpr_free(key_cert_pairs); |
||||
return self; |
||||
} |
||||
|
||||
ServerCredentials *pygrpc_ServerCredentials_fake_transport_security( |
||||
PyTypeObject *type, PyObject *ignored) { |
||||
ServerCredentials *self = (ServerCredentials *)type->tp_alloc(type, 0); |
||||
self->c_creds = grpc_fake_transport_security_server_credentials_create(); |
||||
return self; |
||||
} |
||||
|
@ -0,0 +1,460 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015, Google Inc. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* * Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following disclaimer |
||||
* in the documentation and/or other materials provided with the |
||||
* distribution. |
||||
* * Neither the name of Google Inc. nor the names of its |
||||
* contributors may be used to endorse or promote products derived from |
||||
* this software without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
* |
||||
*/ |
||||
|
||||
#include <math.h> |
||||
|
||||
#define PY_SSIZE_T_CLEAN |
||||
#include <Python.h> |
||||
#include <grpc/grpc.h> |
||||
#include <grpc/support/alloc.h> |
||||
#include <grpc/support/slice.h> |
||||
#include <grpc/support/time.h> |
||||
|
||||
#include "grpc/_adapter/_c/types.h" |
||||
|
||||
pygrpc_tag *pygrpc_produce_batch_tag( |
||||
PyObject *user_tag, Call *call, grpc_op *ops, size_t nops) { |
||||
pygrpc_tag *tag = gpr_malloc(sizeof(pygrpc_tag)); |
||||
tag->user_tag = user_tag; |
||||
Py_XINCREF(tag->user_tag); |
||||
tag->call = call; |
||||
Py_XINCREF(tag->call); |
||||
tag->ops = gpr_malloc(sizeof(grpc_op)*nops); |
||||
memcpy(tag->ops, ops, sizeof(grpc_op)*nops); |
||||
tag->nops = nops; |
||||
grpc_call_details_init(&tag->request_call_details); |
||||
grpc_metadata_array_init(&tag->request_metadata); |
||||
tag->is_new_call = 0; |
||||
return tag; |
||||
} |
||||
|
||||
pygrpc_tag *pygrpc_produce_request_tag(PyObject *user_tag, Call *empty_call) { |
||||
pygrpc_tag *tag = gpr_malloc(sizeof(pygrpc_tag)); |
||||
tag->user_tag = user_tag; |
||||
Py_XINCREF(tag->user_tag); |
||||
tag->call = empty_call; |
||||
Py_XINCREF(tag->call); |
||||
tag->ops = NULL; |
||||
tag->nops = 0; |
||||
grpc_call_details_init(&tag->request_call_details); |
||||
grpc_metadata_array_init(&tag->request_metadata); |
||||
tag->is_new_call = 1; |
||||
return tag; |
||||
} |
||||
|
||||
pygrpc_tag *pygrpc_produce_server_shutdown_tag(PyObject *user_tag) { |
||||
pygrpc_tag *tag = gpr_malloc(sizeof(pygrpc_tag)); |
||||
tag->user_tag = user_tag; |
||||
Py_XINCREF(tag->user_tag); |
||||
tag->call = NULL; |
||||
tag->ops = NULL; |
||||
tag->nops = 0; |
||||
grpc_call_details_init(&tag->request_call_details); |
||||
grpc_metadata_array_init(&tag->request_metadata); |
||||
tag->is_new_call = 0; |
||||
return tag; |
||||
} |
||||
|
||||
void pygrpc_discard_tag(pygrpc_tag *tag) { |
||||
if (!tag) { |
||||
return; |
||||
} |
||||
Py_XDECREF(tag->user_tag); |
||||
Py_XDECREF(tag->call); |
||||
gpr_free(tag->ops); |
||||
grpc_call_details_destroy(&tag->request_call_details); |
||||
grpc_metadata_array_destroy(&tag->request_metadata); |
||||
gpr_free(tag); |
||||
} |
||||
|
||||
PyObject *pygrpc_consume_event(grpc_event event) { |
||||
pygrpc_tag *tag; |
||||
PyObject *result; |
||||
if (event.type == GRPC_QUEUE_TIMEOUT) { |
||||
Py_RETURN_NONE; |
||||
} |
||||
tag = event.tag; |
||||
switch (event.type) { |
||||
case GRPC_QUEUE_SHUTDOWN: |
||||
result = Py_BuildValue("iOOOOO", GRPC_QUEUE_SHUTDOWN, |
||||
Py_None, Py_None, Py_None, Py_None, Py_True); |
||||
break; |
||||
case GRPC_OP_COMPLETE: |
||||
if (tag->is_new_call) { |
||||
result = Py_BuildValue( |
||||
"iOO(ssd)[(iNOOOO)]O", GRPC_OP_COMPLETE, tag->user_tag, tag->call, |
||||
tag->request_call_details.method, tag->request_call_details.host, |
||||
pygrpc_cast_gpr_timespec_to_double(tag->request_call_details.deadline), |
||||
GRPC_OP_RECV_INITIAL_METADATA, |
||||
pygrpc_cast_metadata_array_to_pylist(tag->request_metadata), Py_None, |
||||
Py_None, Py_None, Py_None, |
||||
event.success ? Py_True : Py_False); |
||||
} else { |
||||
result = Py_BuildValue("iOOONO", GRPC_OP_COMPLETE, tag->user_tag, |
||||
tag->call, Py_None, pygrpc_consume_ops(tag->ops, tag->nops), |
||||
event.success ? Py_True : Py_False); |
||||
} |
||||
break; |
||||
default: |
||||
PyErr_SetString(PyExc_ValueError, |
||||
"unknown completion type; could not translate event"); |
||||
return NULL; |
||||
} |
||||
pygrpc_discard_tag(tag); |
||||
return result; |
||||
} |
||||
|
||||
int pygrpc_produce_op(PyObject *op, grpc_op *result) { |
||||
static const int OP_TUPLE_SIZE = 5; |
||||
static const int STATUS_TUPLE_SIZE = 2; |
||||
static const int TYPE_INDEX = 0; |
||||
static const int INITIAL_METADATA_INDEX = 1; |
||||
static const int TRAILING_METADATA_INDEX = 2; |
||||
static const int MESSAGE_INDEX = 3; |
||||
static const int STATUS_INDEX = 4; |
||||
static const int STATUS_CODE_INDEX = 0; |
||||
static const int STATUS_DETAILS_INDEX = 1; |
||||
grpc_op c_op; |
||||
if (!PyTuple_Check(op)) { |
||||
PyErr_SetString(PyExc_TypeError, "expected tuple op"); |
||||
return 0; |
||||
} |
||||
if (PyTuple_Size(op) != OP_TUPLE_SIZE) { |
||||
char buf[64]; |
||||
snprintf(buf, sizeof(buf), "expected tuple op of length %d", OP_TUPLE_SIZE); |
||||
PyErr_SetString(PyExc_ValueError, buf); |
||||
return 0; |
||||
} |
||||
int type = PyInt_AsLong(PyTuple_GET_ITEM(op, TYPE_INDEX)); |
||||
if (PyErr_Occurred()) { |
||||
return 0; |
||||
} |
||||
Py_ssize_t message_size; |
||||
char *message; |
||||
char *status_details; |
||||
gpr_slice message_slice; |
||||
c_op.op = type; |
||||
switch (type) { |
||||
case GRPC_OP_SEND_INITIAL_METADATA: |
||||
if (!pygrpc_cast_pylist_to_send_metadata( |
||||
PyTuple_GetItem(op, INITIAL_METADATA_INDEX), |
||||
&c_op.data.send_initial_metadata.metadata, |
||||
&c_op.data.send_initial_metadata.count)) { |
||||
return 0; |
||||
} |
||||
break; |
||||
case GRPC_OP_SEND_MESSAGE: |
||||
PyString_AsStringAndSize( |
||||
PyTuple_GET_ITEM(op, MESSAGE_INDEX), &message, &message_size); |
||||
message_slice = gpr_slice_from_copied_buffer(message, message_size); |
||||
c_op.data.send_message = grpc_byte_buffer_create(&message_slice, 1); |
||||
gpr_slice_unref(message_slice); |
||||
break; |
||||
case GRPC_OP_SEND_CLOSE_FROM_CLIENT: |
||||
/* Don't need to fill in any other fields. */ |
||||
break; |
||||
case GRPC_OP_SEND_STATUS_FROM_SERVER: |
||||
if (!pygrpc_cast_pylist_to_send_metadata( |
||||
PyTuple_GetItem(op, TRAILING_METADATA_INDEX), |
||||
&c_op.data.send_status_from_server.trailing_metadata, |
||||
&c_op.data.send_status_from_server.trailing_metadata_count)) { |
||||
return 0; |
||||
} |
||||
if (!PyTuple_Check(PyTuple_GET_ITEM(op, STATUS_INDEX))) { |
||||
char buf[64]; |
||||
snprintf(buf, sizeof(buf), "expected tuple status in op of length %d", |
||||
STATUS_TUPLE_SIZE); |
||||
PyErr_SetString(PyExc_TypeError, buf); |
||||
return 0; |
||||
} |
||||
c_op.data.send_status_from_server.status = PyInt_AsLong( |
||||
PyTuple_GET_ITEM(PyTuple_GET_ITEM(op, STATUS_INDEX), STATUS_CODE_INDEX)); |
||||
status_details = PyString_AsString( |
||||
PyTuple_GET_ITEM(PyTuple_GET_ITEM(op, STATUS_INDEX), STATUS_DETAILS_INDEX)); |
||||
if (PyErr_Occurred()) { |
||||
return 0; |
||||
} |
||||
c_op.data.send_status_from_server.status_details = |
||||
gpr_malloc(strlen(status_details) + 1); |
||||
strcpy((char *)c_op.data.send_status_from_server.status_details, |
||||
status_details); |
||||
break; |
||||
case GRPC_OP_RECV_INITIAL_METADATA: |
||||
c_op.data.recv_initial_metadata = gpr_malloc(sizeof(grpc_metadata_array)); |
||||
grpc_metadata_array_init(c_op.data.recv_initial_metadata); |
||||
break; |
||||
case GRPC_OP_RECV_MESSAGE: |
||||
c_op.data.recv_message = gpr_malloc(sizeof(grpc_byte_buffer *)); |
||||
break; |
||||
case GRPC_OP_RECV_STATUS_ON_CLIENT: |
||||
c_op.data.recv_status_on_client.trailing_metadata = |
||||
gpr_malloc(sizeof(grpc_metadata_array)); |
||||
grpc_metadata_array_init(c_op.data.recv_status_on_client.trailing_metadata); |
||||
c_op.data.recv_status_on_client.status = |
||||
gpr_malloc(sizeof(grpc_status_code *)); |
||||
c_op.data.recv_status_on_client.status_details = |
||||
gpr_malloc(sizeof(char *)); |
||||
*c_op.data.recv_status_on_client.status_details = NULL; |
||||
c_op.data.recv_status_on_client.status_details_capacity = |
||||
gpr_malloc(sizeof(size_t)); |
||||
*c_op.data.recv_status_on_client.status_details_capacity = 0; |
||||
break; |
||||
case GRPC_OP_RECV_CLOSE_ON_SERVER: |
||||
c_op.data.recv_close_on_server.cancelled = gpr_malloc(sizeof(int)); |
||||
break; |
||||
default: |
||||
return 0; |
||||
} |
||||
*result = c_op; |
||||
return 1; |
||||
} |
||||
|
||||
void pygrpc_discard_op(grpc_op op) { |
||||
switch(op.op) { |
||||
case GRPC_OP_SEND_INITIAL_METADATA: |
||||
gpr_free(op.data.send_initial_metadata.metadata); |
||||
break; |
||||
case GRPC_OP_SEND_MESSAGE: |
||||
grpc_byte_buffer_destroy(op.data.send_message); |
||||
break; |
||||
case GRPC_OP_SEND_CLOSE_FROM_CLIENT: |
||||
/* Don't need to free any fields. */ |
||||
break; |
||||
case GRPC_OP_SEND_STATUS_FROM_SERVER: |
||||
gpr_free(op.data.send_status_from_server.trailing_metadata); |
||||
gpr_free((char *)op.data.send_status_from_server.status_details); |
||||
break; |
||||
case GRPC_OP_RECV_INITIAL_METADATA: |
||||
grpc_metadata_array_destroy(op.data.recv_initial_metadata); |
||||
gpr_free(op.data.recv_initial_metadata); |
||||
break; |
||||
case GRPC_OP_RECV_MESSAGE: |
||||
grpc_byte_buffer_destroy(*op.data.recv_message); |
||||
gpr_free(op.data.recv_message); |
||||
break; |
||||
case GRPC_OP_RECV_STATUS_ON_CLIENT: |
||||
grpc_metadata_array_destroy(op.data.recv_status_on_client.trailing_metadata); |
||||
gpr_free(op.data.recv_status_on_client.trailing_metadata); |
||||
gpr_free(op.data.recv_status_on_client.status); |
||||
gpr_free(*op.data.recv_status_on_client.status_details); |
||||
gpr_free(op.data.recv_status_on_client.status_details); |
||||
gpr_free(op.data.recv_status_on_client.status_details_capacity); |
||||
break; |
||||
case GRPC_OP_RECV_CLOSE_ON_SERVER: |
||||
gpr_free(op.data.recv_close_on_server.cancelled); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
PyObject *pygrpc_consume_ops(grpc_op *op, size_t nops) { |
||||
static const int TYPE_INDEX = 0; |
||||
static const int INITIAL_METADATA_INDEX = 1; |
||||
static const int TRAILING_METADATA_INDEX = 2; |
||||
static const int MESSAGE_INDEX = 3; |
||||
static const int STATUS_INDEX = 4; |
||||
static const int CANCELLED_INDEX = 5; |
||||
static const int OPRESULT_LENGTH = 6; |
||||
PyObject *list; |
||||
size_t i; |
||||
size_t j; |
||||
char *bytes; |
||||
size_t bytes_size; |
||||
PyObject *results = PyList_New(nops); |
||||
if (!results) { |
||||
return NULL; |
||||
} |
||||
for (i = 0; i < nops; ++i) { |
||||
PyObject *result = PyTuple_Pack(OPRESULT_LENGTH, Py_None, Py_None, Py_None, |
||||
Py_None, Py_None, Py_None); |
||||
PyTuple_SetItem(result, TYPE_INDEX, PyInt_FromLong(op[i].op)); |
||||
switch(op[i].op) { |
||||
case GRPC_OP_RECV_INITIAL_METADATA: |
||||
PyTuple_SetItem(result, INITIAL_METADATA_INDEX, |
||||
list=PyList_New(op[i].data.recv_initial_metadata->count)); |
||||
for (j = 0; j < op[i].data.recv_initial_metadata->count; ++j) { |
||||
grpc_metadata md = op[i].data.recv_initial_metadata->metadata[j]; |
||||
PyList_SetItem(list, j, Py_BuildValue("ss#", md.key, md.value, |
||||
(Py_ssize_t)md.value_length)); |
||||
} |
||||
break; |
||||
case GRPC_OP_RECV_MESSAGE: |
||||
if (*op[i].data.recv_message) { |
||||
pygrpc_byte_buffer_to_bytes( |
||||
*op[i].data.recv_message, &bytes, &bytes_size); |
||||
PyTuple_SetItem(result, MESSAGE_INDEX, |
||||
PyString_FromStringAndSize(bytes, bytes_size)); |
||||
gpr_free(bytes); |
||||
} else { |
||||
PyTuple_SetItem(result, MESSAGE_INDEX, Py_BuildValue("")); |
||||
} |
||||
break; |
||||
case GRPC_OP_RECV_STATUS_ON_CLIENT: |
||||
PyTuple_SetItem( |
||||
result, TRAILING_METADATA_INDEX, |
||||
list = PyList_New(op[i].data.recv_status_on_client.trailing_metadata->count)); |
||||
for (j = 0; j < op[i].data.recv_status_on_client.trailing_metadata->count; ++j) { |
||||
grpc_metadata md = |
||||
op[i].data.recv_status_on_client.trailing_metadata->metadata[j]; |
||||
PyList_SetItem(list, j, Py_BuildValue("ss#", md.key, md.value, |
||||
(Py_ssize_t)md.value_length)); |
||||
} |
||||
PyTuple_SetItem( |
||||
result, STATUS_INDEX, Py_BuildValue( |
||||
"is", *op[i].data.recv_status_on_client.status, |
||||
*op[i].data.recv_status_on_client.status_details)); |
||||
break; |
||||
case GRPC_OP_RECV_CLOSE_ON_SERVER: |
||||
PyTuple_SetItem( |
||||
result, CANCELLED_INDEX, |
||||
PyBool_FromLong(*op[i].data.recv_close_on_server.cancelled)); |
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
pygrpc_discard_op(op[i]); |
||||
PyList_SetItem(results, i, result); |
||||
} |
||||
return results; |
||||
} |
||||
|
||||
double pygrpc_cast_gpr_timespec_to_double(gpr_timespec timespec) { |
||||
return timespec.tv_sec + 1e-9*timespec.tv_nsec; |
||||
} |
||||
|
||||
gpr_timespec pygrpc_cast_double_to_gpr_timespec(double seconds) { |
||||
gpr_timespec result; |
||||
if isinf(seconds) { |
||||
result = seconds > 0.0 ? gpr_inf_future : gpr_inf_past; |
||||
} else { |
||||
result.tv_sec = (time_t)seconds; |
||||
result.tv_nsec = ((seconds - result.tv_sec) * 1e9); |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
int pygrpc_produce_channel_args(PyObject *py_args, grpc_channel_args *c_args) { |
||||
size_t num_args = PyList_Size(py_args); |
||||
size_t i; |
||||
grpc_channel_args args = {num_args, gpr_malloc(sizeof(grpc_arg) * num_args)}; |
||||
for (i = 0; i < args.num_args; ++i) { |
||||
char *key; |
||||
PyObject *value; |
||||
if (!PyArg_ParseTuple(PyList_GetItem(py_args, i), "zO", &key, &value)) { |
||||
gpr_free(args.args); |
||||
args.num_args = 0; |
||||
args.args = NULL; |
||||
PyErr_SetString(PyExc_TypeError, |
||||
"expected a list of 2-tuple of str and str|int|None"); |
||||
return 0; |
||||
} |
||||
args.args[i].key = key; |
||||
if (PyInt_Check(value)) { |
||||
args.args[i].type = GRPC_ARG_INTEGER; |
||||
args.args[i].value.integer = PyInt_AsLong(value); |
||||
} else if (PyString_Check(value)) { |
||||
args.args[i].type = GRPC_ARG_STRING; |
||||
args.args[i].value.string = PyString_AsString(value); |
||||
} else if (value == Py_None) { |
||||
--args.num_args; |
||||
--i; |
||||
continue; |
||||
} else { |
||||
gpr_free(args.args); |
||||
args.num_args = 0; |
||||
args.args = NULL; |
||||
PyErr_SetString(PyExc_TypeError, |
||||
"expected a list of 2-tuple of str and str|int|None"); |
||||
return 0; |
||||
} |
||||
} |
||||
*c_args = args; |
||||
return 1; |
||||
} |
||||
|
||||
void pygrpc_discard_channel_args(grpc_channel_args args) { |
||||
gpr_free(args.args); |
||||
} |
||||
|
||||
int pygrpc_cast_pylist_to_send_metadata( |
||||
PyObject *pylist, grpc_metadata **metadata, size_t *count) { |
||||
size_t i; |
||||
Py_ssize_t value_length; |
||||
*count = PyList_Size(pylist); |
||||
*metadata = gpr_malloc(sizeof(grpc_metadata) * *count); |
||||
for (i = 0; i < *count; ++i) { |
||||
if (!PyArg_ParseTuple( |
||||
PyList_GetItem(pylist, i), "ss#", |
||||
&(*metadata)[i].key, &(*metadata)[i].value, &value_length)) { |
||||
gpr_free(*metadata); |
||||
*count = 0; |
||||
*metadata = NULL; |
||||
return 0; |
||||
} |
||||
(*metadata)[i].value_length = value_length; |
||||
} |
||||
return 1; |
||||
} |
||||
|
||||
PyObject *pygrpc_cast_metadata_array_to_pylist(grpc_metadata_array metadata) { |
||||
PyObject *result = PyList_New(metadata.count); |
||||
size_t i; |
||||
for (i = 0; i < metadata.count; ++i) { |
||||
PyList_SetItem( |
||||
result, i, Py_BuildValue( |
||||
"ss#", metadata.metadata[i].key, metadata.metadata[i].value, |
||||
(Py_ssize_t)metadata.metadata[i].value_length)); |
||||
if (PyErr_Occurred()) { |
||||
Py_DECREF(result); |
||||
return NULL; |
||||
} |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
void pygrpc_byte_buffer_to_bytes( |
||||
grpc_byte_buffer *buffer, char **result, size_t *result_size) { |
||||
grpc_byte_buffer_reader *reader = grpc_byte_buffer_reader_create(buffer); |
||||
gpr_slice slice; |
||||
char *read_result = NULL; |
||||
size_t size = 0; |
||||
while (grpc_byte_buffer_reader_next(reader, &slice)) { |
||||
read_result = gpr_realloc(read_result, size + GPR_SLICE_LENGTH(slice)); |
||||
memcpy(read_result + size, GPR_SLICE_START_PTR(slice), |
||||
GPR_SLICE_LENGTH(slice)); |
||||
size = size + GPR_SLICE_LENGTH(slice); |
||||
gpr_slice_unref(slice); |
||||
} |
||||
grpc_byte_buffer_reader_destroy(reader); |
||||
*result_size = size; |
||||
*result = read_result; |
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue