1 /* transport - low level communication */
3 /* Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010. The SimGrid Team.
4 * All rights reserved. */
6 /* This program is free software; you can redistribute it and/or modify it
7 * under the terms of the license (GNU LGPL) which comes with this package. */
13 static int gras_opt_trp_nomoredata_on_close = 0;
18 #include "xbt/socket.h"
19 #include "xbt/xbt_socket_private.h" /* FIXME */
21 #include "gras/Transport/transport_private.h"
22 #include "gras/Msg/msg_interface.h"
24 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(gras_trp, gras,
25 "Conveying bytes over the network");
28 * @brief Opens a server socket and makes it ready to be listened to.
29 * @param port: port on which you want to listen
30 * @param buf_size: size of the buffer (in byte) on the socket (for TCP sockets only). If 0, a sain default is used (32k, but may change)
31 * @param measurement: whether this socket is meant to convey measurement (if you don't know, use 0 to exchange regular messages)
33 * In real life, you'll get a TCP socket.
36 gras_socket_server_ext(unsigned short port,
37 unsigned long int buf_size, int measurement)
42 XBT_DEBUG("Create a server socket from plugin %s on port %d",
43 gras_if_RL() ? "tcp" : "sg", port);
44 trp = xbt_trp_plugin_get_by_name(gras_if_SG() ? "sg" : "tcp");
46 /* defaults settings */
50 (buf_size > 0 ? buf_size : 32 * 1024),
53 /* Call plugin socket creation function */
54 XBT_DEBUG("Prepare socket with plugin (fct=%p)", trp->socket_server);
56 trp->socket_server(trp, port, sock);
64 ((gras_trp_procdata_t) gras_libdata_by_id(gras_trp_libdata_id))->myport
66 xbt_dynar_push(((gras_trp_procdata_t)
67 gras_libdata_by_id(gras_trp_libdata_id))->sockets,
70 gras_msg_listener_awake();
75 * @brief Opens a server socket on any port in the given range
77 * @param minport: first port we will try
78 * @param maxport: last port we will try
79 * @param buf_size: size of the buffer (in byte) on the socket (for TCP sockets only). If 0, a sain default is used (32k, but may change)
80 * @param measurement: whether this socket is meant to convey measurement (if you don't know, use 0 to exchange regular messages)
82 * If none of the provided ports works, raises the exception got when trying the last possibility
85 gras_socket_server_range(unsigned short minport, unsigned short maxport,
86 unsigned long int buf_size, int measurement)
90 xbt_socket_t res = NULL;
93 for (port = minport; port < maxport; port++) {
95 res = gras_socket_server_ext(port, buf_size, measurement);
109 * @brief Opens a client socket to a remote host.
110 * @param host: who you want to connect to
111 * @param port: where you want to connect to on this host
112 * @param buf_size: size of the buffer (in bytes) on the socket (for TCP sockets only). If 0, a sain default is used (32k, but may change)
113 * @param measurement: whether this socket is meant to convey measurement (if you don't know, use 0 to exchange regular messages)
115 * In real life, you'll get a TCP socket.
118 gras_socket_client_ext(const char *host,
120 unsigned long int buf_size, int measurement)
122 xbt_trp_plugin_t trp;
125 trp = xbt_trp_plugin_get_by_name(gras_if_SG() ? "sg" : "tcp");
127 XBT_DEBUG("Create a client socket from plugin %s",
128 gras_if_RL()? "tcp" : "sg");
129 /* defaults settings */
130 xbt_socket_new_ext(0,
133 (buf_size > 0 ? buf_size : 32 * 1024),
136 /* plugin-specific */
138 (*trp->socket_client) (trp, host, port, sock);
144 xbt_dynar_push(((gras_trp_procdata_t)
145 gras_libdata_by_id(gras_trp_libdata_id))->sockets,
147 gras_msg_listener_awake();
152 * @brief Opens a server socket and make it ready to be listened to.
154 * In real life, you'll get a TCP socket.
156 xbt_socket_t gras_socket_server(unsigned short port)
158 return gras_socket_server_ext(port, 32 * 1024, 0);
161 /** @brief Opens a client socket to a remote host */
162 xbt_socket_t gras_socket_client(const char *host, unsigned short port)
164 return gras_socket_client_ext(host, port, 0, 0);
167 /** @brief Opens a client socket to a remote host specified as '\a host:\a port' */
168 xbt_socket_t gras_socket_client_from_string(const char *host)
170 xbt_peer_t p = xbt_peer_from_string(host);
171 xbt_socket_t res = gras_socket_client_ext(p->name, p->port, 0, 0);
176 void gras_socket_close_voidp(void *sock)
178 gras_socket_close((xbt_socket_t) sock);
181 /** \brief Close socket */
182 void gras_socket_close(xbt_socket_t sock)
184 if (--sock->refcount)
187 xbt_dynar_t sockets =
188 ((gras_trp_procdata_t)
189 gras_libdata_by_id(gras_trp_libdata_id))->sockets;
190 xbt_socket_t sock_iter = NULL;
194 XBT_VERB("Close %p", sock);
195 if (sock == _gras_lastly_selected_socket) {
196 xbt_assert(!gras_opt_trp_nomoredata_on_close || !sock->moredata,
197 "Closing a socket having more data in buffer while the nomoredata_on_close option is activated");
201 ("Closing a socket having more data in buffer. Option nomoredata_on_close disabled, so continuing.");
202 _gras_lastly_selected_socket = NULL;
205 /* FIXME: Issue an event when the socket is closed */
206 XBT_DEBUG("sockets pointer before %p", sockets);
208 /* FIXME: Cannot get the dynar mutex, because it can be already locked */
209 // _xbt_dynar_foreach(sockets,cursor,sock_iter) {
210 for (cursor = 0; cursor < xbt_dynar_length(sockets); cursor++) {
211 _xbt_dynar_cursor_get(sockets, cursor, &sock_iter);
212 if (sock == sock_iter) {
213 XBT_DEBUG("remove sock cursor %u dize %lu\n", cursor,
214 xbt_dynar_length(sockets));
215 xbt_dynar_cursor_rm(sockets, &cursor);
216 if (sock->plugin->socket_close)
217 (*sock->plugin->socket_close) (sock);
219 /* free the memory */
226 ("Ignoring request to free an unknown socket (%p). Execution stack:",
228 xbt_backtrace_display_current();
234 * Creating procdata for this module
236 static void *gras_trp_procdata_new(void)
238 gras_trp_procdata_t res = xbt_new(s_gras_trp_procdata_t, 1);
240 res->name = xbt_strdup("gras_trp");
242 res->sockets = xbt_dynar_new_sync(sizeof(xbt_socket_t *), NULL);
249 * Freeing procdata for this module
251 static void gras_trp_procdata_free(void *data)
253 gras_trp_procdata_t res = (gras_trp_procdata_t) data;
255 xbt_dynar_free(&(res->sockets));
260 void gras_trp_socketset_dump(const char *name)
262 gras_trp_procdata_t procdata =
263 (gras_trp_procdata_t) gras_libdata_by_id(gras_trp_libdata_id);
268 XBT_INFO("** Dump the socket set %s", name);
269 xbt_dynar_foreach(procdata->sockets, it, s) {
270 XBT_INFO(" %p -> %s:%d %s",
271 s, xbt_socket_peer_name(s), xbt_socket_peer_port(s),
272 s->valid ? "(valid)" : "(peer dead)");
274 XBT_INFO("** End of socket set %s", name);
278 * Module registration
280 int gras_trp_libdata_id;
281 void gras_trp_register()
283 gras_trp_libdata_id =
284 gras_procdata_add("gras_trp", gras_trp_procdata_new,
285 gras_trp_procdata_free);
288 int gras_os_myport(void)
290 return ((gras_trp_procdata_t)
291 gras_libdata_by_id(gras_trp_libdata_id))->myport;