| 172 | } |
| 173 | |
| 174 | Status PyFlightServer::ServeWithSignals() { |
| 175 | // Respect the current Python settings, i.e. only interrupt the server if there is |
| 176 | // an active signal handler for SIGINT and SIGTERM. |
| 177 | std::vector<int> signals; |
| 178 | for (const int signum : {SIGINT, SIGTERM}) { |
| 179 | ARROW_ASSIGN_OR_RAISE(auto handler, ::arrow::internal::GetSignalHandler(signum)); |
| 180 | auto cb = handler.callback(); |
| 181 | if (cb != SIG_DFL && cb != SIG_IGN) { |
| 182 | signals.push_back(signum); |
| 183 | } |
| 184 | } |
| 185 | RETURN_NOT_OK(SetShutdownOnSignals(signals)); |
| 186 | |
| 187 | // Serve until we got told to shutdown or a signal interrupted us |
| 188 | RETURN_NOT_OK(Serve()); |
| 189 | int signum = GotSignal(); |
| 190 | if (signum != 0) { |
| 191 | // Issue the signal again with Python's signal handlers restored |
| 192 | PyAcquireGIL lock; |
| 193 | raise(signum); |
| 194 | // XXX Ideally we would loop and serve again if no exception was raised. |
| 195 | // Unfortunately, gRPC will return immediately if Serve() is called again. |
| 196 | ARROW_UNUSED(PyErr_CheckSignals()); |
| 197 | } |
| 198 | |
| 199 | return Status::OK(); |
| 200 | } |
| 201 | |
| 202 | PyFlightResultStream::PyFlightResultStream(PyObject* generator, |
| 203 | PyFlightResultStreamCallback callback) |