| 76 | } |
| 77 | |
| 78 | void 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 | |
| 128 | void ServerThread::preServe() { |
| 129 | // We bound to the port successfully, and are about to start serving requests |
nothing calls this directly
no test coverage detected