blob: 13eec277a452b5218e2f564e60e209b70ce02897 [file] [log] [blame]
Roger Meier15df0762014-09-29 20:50:56 +02001/*
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
20#include <glib-object.h>
21#include <signal.h>
22#include <stdio.h>
23#include <string.h>
24
25#include <thrift/c_glib/thrift.h>
26#include <thrift/c_glib/protocol/thrift_binary_protocol_factory.h>
27#include <thrift/c_glib/server/thrift_server.h>
28#include <thrift/c_glib/server/thrift_simple_server.h>
29#include <thrift/c_glib/transport/thrift_buffered_transport.h>
30#include <thrift/c_glib/transport/thrift_buffered_transport_factory.h>
31#include <thrift/c_glib/transport/thrift_framed_transport.h>
32#include <thrift/c_glib/transport/thrift_framed_transport_factory.h>
33#include <thrift/c_glib/transport/thrift_server_socket.h>
34#include <thrift/c_glib/transport/thrift_server_transport.h>
35#include <thrift/c_glib/transport/thrift_transport.h>
36#include <thrift/c_glib/transport/thrift_transport_factory.h>
37
38#include "../gen-c_glib/t_test_thrift_test.h"
39
40#include "thrift_test_handler.h"
41
42/* Our server object, declared globally so it is accessible within the SIGINT
43 signal handler */
44ThriftServer *server = NULL;
45
46/* A flag that indicates whether the server was interrupted with SIGINT
47 (i.e. Ctrl-C) so we can tell whether its termination was abnormal */
48gboolean sigint_received = FALSE;
49
50/* Handle SIGINT ("Ctrl-C") signals by gracefully stopping the server */
51static void
52sigint_handler (int signal_number)
53{
54 THRIFT_UNUSED_VAR (signal_number);
55
56 /* Take note we were called */
57 sigint_received = TRUE;
58
59 /* Shut down the server gracefully */
60 if (server != NULL)
61 thrift_server_stop (server);
62}
63
64int
65main (int argc, char **argv)
66{
67 static gint port = 9090;
68 static gchar *server_type_option = NULL;
69 static gchar *transport_option = NULL;
70 static gchar *protocol_option = NULL;
71
72 static
73 GOptionEntry option_entries[] = {
74 { "port", 0, 0, G_OPTION_ARG_INT, &port,
75 "Port number to connect (=9090)", NULL },
76 { "server-type", 0, 0, G_OPTION_ARG_STRING, &server_type_option,
77 "Type of server: simple (=simple)", NULL },
78 { "transport", 0, 0, G_OPTION_ARG_STRING, &transport_option,
79 "Transport: buffered, framed (=buffered)", NULL },
80 { "protocol", 0, 0, G_OPTION_ARG_STRING, &protocol_option,
81 "Protocol: binary (=binary)", NULL },
82 { NULL }
83 };
84
85 gchar *server_name = "simple";
86 gchar *transport_name = "buffered";
87 GType transport_factory_type = THRIFT_TYPE_BUFFERED_TRANSPORT_FACTORY;
88 gchar *protocol_name = "binary";
89 GType protocol_factory_type = THRIFT_TYPE_BINARY_PROTOCOL_FACTORY;
90
91 TTestThriftTestHandler *handler;
92 ThriftProcessor *processor;
93 ThriftServerTransport *server_transport;
94 ThriftTransportFactory *transport_factory;
95 ThriftProtocolFactory *protocol_factory;
96
97 struct sigaction sigint_action;
98
99 GOptionContext *option_context;
100 gboolean options_valid = TRUE;
101
102 GError *error = NULL;
103
104#if (!GLIB_CHECK_VERSION (2, 36, 0))
105 g_type_init ();
106#endif
107
108 /* Configure and parse our command-line options */
109 option_context = g_option_context_new (NULL);
110 g_option_context_add_main_entries (option_context,
111 option_entries,
112 NULL);
113 if (g_option_context_parse (option_context,
114 &argc,
115 &argv,
116 &error) == FALSE) {
117 fprintf (stderr, "%s\n", error->message);
118 return 255;
119 }
120 g_option_context_free (option_context);
121
122 /* Validate the parsed options */
123 if (server_type_option != NULL &&
124 strncmp (server_type_option, "simple", 7) != 0) {
125 fprintf (stderr, "Unknown server type %s\n", protocol_option);
126 options_valid = FALSE;
127 }
128
129 if (protocol_option != NULL &&
130 strncmp (protocol_option, "binary", 7) != 0) {
131 fprintf (stderr, "Unknown protocol type %s\n", protocol_option);
132 options_valid = FALSE;
133 }
134
135 if (transport_option != NULL) {
136 if (strncmp (transport_option, "framed", 7) == 0) {
137 transport_factory_type = THRIFT_TYPE_FRAMED_TRANSPORT_FACTORY;
138 transport_name = "framed";
139 }
140 else if (strncmp (transport_option, "buffered", 9) != 0) {
141 fprintf (stderr, "Unknown transport type %s\n", transport_option);
142 options_valid = FALSE;
143 }
144 }
145
146 if (!options_valid)
147 return 254;
148
149 /* Establish all our connection objects */
150 handler = g_object_new (TYPE_THRIFT_TEST_HANDLER,
151 NULL);
152 processor = g_object_new (T_TEST_TYPE_THRIFT_TEST_PROCESSOR,
153 "handler", handler,
154 NULL);
155 server_transport = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
156 "port", port,
157 NULL);
158 transport_factory = g_object_new (transport_factory_type,
159 NULL);
160 protocol_factory = g_object_new (protocol_factory_type,
161 NULL);
162
163 server = g_object_new (THRIFT_TYPE_SIMPLE_SERVER,
164 "processor", processor,
165 "server_transport", server_transport,
166 "input_transport_factory", transport_factory,
167 "output_transport_factory", transport_factory,
168 "input_protocol_factory", protocol_factory,
169 "output_protocol_factory", protocol_factory,
170 NULL);
171
172 /* Install our SIGINT handler, which handles Ctrl-C being pressed by stopping
173 the server gracefully */
174 memset (&sigint_action, 0, sizeof (sigint_action));
175 sigint_action.sa_handler = sigint_handler;
176 sigint_action.sa_flags = SA_RESETHAND;
177 sigaction (SIGINT, &sigint_action, NULL);
178
179 printf ("Starting \"%s\" server (%s/%s) listen on: %d\n",
180 server_name,
181 transport_name,
182 protocol_name,
183 port);
184 fflush (stdout);
185
186 /* Serve clients until SIGINT is received (Ctrl-C is pressed) */
187 thrift_server_serve (server, &error);
188
189 /* If the server stopped for any reason other than being interrupted by the
190 user, report the error */
191 if (!sigint_received) {
192 g_message ("thrift_server_serve: %s",
193 error != NULL ? error->message : "(null)");
194 g_clear_error (&error);
195 }
196
197 puts ("done.");
198
199 g_object_unref (server);
200 g_object_unref (protocol_factory);
201 g_object_unref (transport_factory);
202 g_object_unref (server_transport);
203 g_object_unref (processor);
204 g_object_unref (handler);
205
206 return 0;
207}