]> git.proxmox.com Git - ceph.git/blame - ceph/src/jaegertracing/thrift/lib/cpp/test/processor/ServerThread.cpp
buildsys: switch source download to quincy
[ceph.git] / ceph / src / jaegertracing / thrift / lib / cpp / test / processor / ServerThread.cpp
CommitLineData
f67539c2
TL
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19#ifndef _THRIFT_TEST_SERVERTHREAD_TCC_
20#define _THRIFT_TEST_SERVERTHREAD_TCC_ 1
21
22#include "ServerThread.h"
23
24#include <thrift/concurrency/ThreadFactory.h>
25#include <thrift/concurrency/ThreadManager.h>
26#include <thrift/server/TThreadPoolServer.h>
27#include <thrift/transport/TBufferTransports.h>
28#include <thrift/transport/TServerSocket.h>
29
30namespace apache {
31namespace thrift {
32namespace test {
33
34void ServerThread::start() {
35 assert(!running_);
36 running_ = true;
37
38 helper_.reset(new Helper(this));
39
40 // Start the other thread
41 concurrency::ThreadFactory threadFactory;
42 threadFactory.setDetached(false);
43 thread_ = threadFactory.newThread(helper_);
44
45 thread_->start();
46
47 // Wait on the other thread to tell us that it has successfully
48 // bound to the port and started listening (or until an error occurs).
49 concurrency::Synchronized s(serverMonitor_);
50 while (!serving_ && !error_) {
51 serverMonitor_.waitForever();
52 }
53
54 if (error_) {
55 throw transport::TTransportException(transport::TTransportException::NOT_OPEN,
56 "failed to bind on server socket");
57 }
58}
59
60void ServerThread::stop() {
61 if (!running_) {
62 return;
63 }
64
65 // Tell the server to stop
66 server_->stop();
67 running_ = false;
68
69 // Wait for the server thread to exit
70 //
71 // Note: this only works if all client connections have closed. The servers
72 // generally wait for everything to be closed before exiting; there currently
73 // isn't a way to tell them to just exit now, and shut down existing
74 // connections.
75 thread_->join();
76}
77
78void ServerThread::run() {
79 /*
80 * Try binding to several ports, in case the one we want is already in use.
81 */
82 port_ = 12345;
83 unsigned int maxRetries = 10;
84 for (unsigned int n = 0; n < maxRetries; ++n) {
85 // Create the server
86 server_ = serverState_->createServer(port_);
87 // Install our helper as the server event handler, so that our
88 // preServe() method will be called once we've successfully bound to
89 // the port and are about to start listening.
90 server_->setServerEventHandler(helper_);
91
92 try {
93 // Try to serve requests
94 server_->serve();
95 } catch (const TException&) {
96 // TNonblockingServer throws a generic TException if it fails to bind.
97 // If we get a TException, we'll optimistically assume the bind failed.
98 ++port_;
99 continue;
100 }
101
102 // Seriously? serve() is pretty lame. If it fails to start serving it
103 // just returns rather than throwing an exception.
104 //
105 // We have to use our preServe() hook to tell if serve() successfully
106 // started serving and is returning because stop() is called, or if it just
107 // failed to start serving in the first place.
108 concurrency::Synchronized s(serverMonitor_);
109 if (serving_) {
110 // Oh good, we started serving and are exiting because
111 // we're trying to stop.
112 serving_ = false;
113 return;
114 } else {
115 // We never started serving, probably because we failed to bind to the
116 // port. Increment the port number and try again.
117 ++port_;
118 continue;
119 }
120 }
121
122 // We failed to bind on any port.
123 concurrency::Synchronized s(serverMonitor_);
124 error_ = true;
125 serverMonitor_.notify();
126}
127
128void ServerThread::preServe() {
129 // We bound to the port successfully, and are about to start serving requests
130 serverState_->bindSuccessful(port_);
131
132 // Set the real server event handler (replacing ourself)
133 std::shared_ptr<server::TServerEventHandler> serverEventHandler
134 = serverState_->getServerEventHandler();
135 server_->setServerEventHandler(serverEventHandler);
136
137 // Notify the main thread that we have successfully started serving requests
138 concurrency::Synchronized s(serverMonitor_);
139 serving_ = true;
140 serverMonitor_.notify();
141
142 // Invoke preServe() on the real event handler, since we ate
143 // the original preServe() event.
144 if (serverEventHandler) {
145 serverEventHandler->preServe();
146 }
147}
148}
149}
150} // apache::thrift::test
151
152#endif // _THRIFT_TEST_SERVERTHREAD_TCC_