blob: 079e046458ff748890f01357bfb8dcd46833cf03 [file] [log] [blame]
Mark Slee9f0c6512007-02-28 23:58:26 +00001// Copyright (c) 2006- Facebook
2// Distributed under the Thrift Software License
3//
4// See accompanying file LICENSE or visit the Thrift site at:
5// http://developers.facebook.com/thrift/
6
Mark Sleeb3cb6292007-02-01 22:55:00 +00007#include "server/TThreadedServer.h"
8#include "transport/TTransportException.h"
9#include "concurrency/PosixThreadFactory.h"
10
11#include <string>
12#include <iostream>
13#include <pthread.h>
14#include <unistd.h>
15
16namespace facebook { namespace thrift { namespace server {
17
Mark Slee5ea15f92007-03-05 22:55:59 +000018using boost::shared_ptr;
Mark Sleeb3cb6292007-02-01 22:55:00 +000019using namespace std;
20using namespace facebook::thrift;
Mark Slee5ea15f92007-03-05 22:55:59 +000021using namespace facebook::thrift::protocol;
Mark Sleeb3cb6292007-02-01 22:55:00 +000022using namespace facebook::thrift::transport;
23using namespace facebook::thrift::concurrency;
24
25class TThreadedServer::Task: public Runnable {
26
27public:
28
29 Task(shared_ptr<TProcessor> processor,
30 shared_ptr<TProtocol> input,
31 shared_ptr<TProtocol> output) :
32 processor_(processor),
33 input_(input),
34 output_(output) {
35 }
36
37 ~Task() {}
38
39 void run() {
40 try {
41 while (processor_->process(input_, output_)) {
42 if (!input_->getTransport()->peek()) {
43 break;
44 }
45 }
46 } catch (TTransportException& ttx) {
47 cerr << "TThreadedServer client died: " << ttx.what() << endl;
48 } catch (TException& x) {
49 cerr << "TThreadedServer exception: " << x.what() << endl;
50 } catch (...) {
51 cerr << "TThreadedServer uncaught exception." << endl;
52 }
53 input_->getTransport()->close();
54 output_->getTransport()->close();
55 }
56
57 private:
58 shared_ptr<TProcessor> processor_;
59 shared_ptr<TProtocol> input_;
60 shared_ptr<TProtocol> output_;
61
62};
63
64
65TThreadedServer::TThreadedServer(shared_ptr<TProcessor> processor,
66 shared_ptr<TServerTransport> serverTransport,
67 shared_ptr<TTransportFactory> transportFactory,
68 shared_ptr<TProtocolFactory> protocolFactory):
69 TServer(processor, serverTransport, transportFactory, protocolFactory) {
70 threadFactory_ = shared_ptr<PosixThreadFactory>(new PosixThreadFactory());
71}
72
73TThreadedServer::~TThreadedServer() {}
74
75void TThreadedServer::serve() {
76
77 shared_ptr<TTransport> client;
78 shared_ptr<TTransport> inputTransport;
79 shared_ptr<TTransport> outputTransport;
80 shared_ptr<TProtocol> inputProtocol;
81 shared_ptr<TProtocol> outputProtocol;
82
83 try {
84 // Start the server listening
85 serverTransport_->listen();
86 } catch (TTransportException& ttx) {
87 cerr << "TThreadedServer::run() listen(): " << ttx.what() << endl;
88 return;
89 }
90
91 while (true) {
92 try {
93 // Fetch client from server
94 client = serverTransport_->accept();
95 // Make IO transports
96 inputTransport = inputTransportFactory_->getTransport(client);
97 outputTransport = outputTransportFactory_->getTransport(client);
98 inputProtocol = inputProtocolFactory_->getProtocol(inputTransport);
99 outputProtocol = outputProtocolFactory_->getProtocol(outputTransport);
100
101 TThreadedServer::Task* t = new TThreadedServer::Task(processor_,
102 inputProtocol,
103 outputProtocol);
104
105 // Create a thread for this task
106 shared_ptr<Thread> thread =
107 shared_ptr<Thread>(threadFactory_->newThread(shared_ptr<Runnable>(t)));
108
109 // Start the thread!
110 thread->start();
111
112 } catch (TTransportException& ttx) {
Mark Slee907e3d62007-02-08 22:29:24 +0000113 inputTransport->close();
114 outputTransport->close();
115 client->close();
116 cerr << "TThreadedServer: TServerTransport died on accept: " << ttx.what() << endl;
117 continue;
118 } catch (TException& tx) {
119 inputTransport->close();
120 outputTransport->close();
121 client->close();
122 cerr << "TThreadedServer: Caught TException: " << tx.what() << endl;
123 continue;
124 } catch (string s) {
125 inputTransport->close();
126 outputTransport->close();
127 client->close();
128 cerr << "TThreadedServer: Unknown exception: " << s << endl;
Mark Sleeb3cb6292007-02-01 22:55:00 +0000129 break;
130 }
131 }
132}
133
134}}} // facebook::thrift::server