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. */
12 static int gras_opt_trp_nomoredata_on_close = 0;
16 #include "xbt/socket.h"
17 #include "xbt/xbt_socket_private.h" /* FIXME */
19 #include "gras/Transport/transport_private.h"
20 #include "gras/Msg/msg_interface.h"
22 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(gras_trp, gras,
23 "Conveying bytes over the network");
26 * @brief Opens a server socket and makes it ready to be listened to.
27 * @param port: port on which you want to listen
28 * @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)
29 * @param measurement: whether this socket is meant to convey measurement (if you don't know, use 0 to exchange regular messages)
31 * In real life, you'll get a TCP socket.
34 gras_socket_server_ext(unsigned short port,
35 unsigned long int buf_size, int measurement)
40 XBT_DEBUG("Create a server socket from plugin %s on port %d",
41 gras_if_RL() ? "tcp" : "sg", port);
42 trp = xbt_trp_plugin_get_by_name(gras_if_SG() ? "sg" : "tcp");
44 /* defaults settings */
48 (buf_size > 0 ? buf_size : 32 * 1024),
51 /* Call plugin socket creation function */
52 XBT_DEBUG("Prepare socket with plugin (fct=%p)", trp->socket_server);
54 trp->socket_server(trp, port, sock);
62 ((gras_trp_procdata_t) gras_libdata_by_id(gras_trp_libdata_id))->myport
64 xbt_dynar_push(((gras_trp_procdata_t)
65 gras_libdata_by_id(gras_trp_libdata_id))->sockets,
68 gras_msg_listener_awake();
73 * @brief Opens a server socket on any port in the given range
75 * @param minport: first port we will try
76 * @param maxport: last port we will try
77 * @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)
78 * @param measurement: whether this socket is meant to convey measurement (if you don't know, use 0 to exchange regular messages)
80 * If none of the provided ports works, raises the exception got when trying the last possibility
83 gras_socket_server_range(unsigned short minport, unsigned short maxport,
84 unsigned long int buf_size, int measurement)
88 xbt_socket_t res = NULL;
91 for (port = minport; port < maxport; port++) {
93 res = gras_socket_server_ext(port, buf_size, measurement);
107 * @brief Opens a client socket to a remote host.
108 * @param host: who you want to connect to
109 * @param port: where you want to connect to on this host
110 * @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)
111 * @param measurement: whether this socket is meant to convey measurement (if you don't know, use 0 to exchange regular messages)
113 * In real life, you'll get a TCP socket.
116 gras_socket_client_ext(const char *host,
118 unsigned long int buf_size, int measurement)
120 xbt_trp_plugin_t trp;
123 trp = xbt_trp_plugin_get_by_name(gras_if_SG() ? "sg" : "tcp");
125 XBT_DEBUG("Create a client socket from plugin %s",
126 gras_if_RL()? "tcp" : "sg");
127 /* defaults settings */
128 xbt_socket_new_ext(0,
131 (buf_size > 0 ? buf_size : 32 * 1024),
134 /* plugin-specific */
136 (*trp->socket_client) (trp, host, port, sock);
142 xbt_dynar_push(((gras_trp_procdata_t)
143 gras_libdata_by_id(gras_trp_libdata_id))->sockets,
145 gras_msg_listener_awake();
150 * @brief Opens a server socket and make it ready to be listened to.
152 * In real life, you'll get a TCP socket.
154 xbt_socket_t gras_socket_server(unsigned short port)
156 return gras_socket_server_ext(port, 32 * 1024, 0);
159 /** @brief Opens a client socket to a remote host */
160 xbt_socket_t gras_socket_client(const char *host, unsigned short port)
162 return gras_socket_client_ext(host, port, 0, 0);
165 /** @brief Opens a client socket to a remote host specified as '\a host:\a port' */
166 xbt_socket_t gras_socket_client_from_string(const char *host)
168 xbt_peer_t p = xbt_peer_from_string(host);
169 xbt_socket_t res = gras_socket_client_ext(p->name, p->port, 0, 0);
174 void gras_socket_close_voidp(void *sock)
176 gras_socket_close((xbt_socket_t) sock);
179 /** \brief Close socket */
180 void gras_socket_close(xbt_socket_t sock)
182 if (--sock->refcount)
185 xbt_dynar_t sockets =
186 ((gras_trp_procdata_t)
187 gras_libdata_by_id(gras_trp_libdata_id))->sockets;
188 xbt_socket_t sock_iter = NULL;
192 XBT_VERB("Close %p", sock);
193 if (sock == _gras_lastly_selected_socket) {
194 xbt_assert(!gras_opt_trp_nomoredata_on_close || !sock->moredata,
195 "Closing a socket having more data in buffer while the nomoredata_on_close option is activated");
199 ("Closing a socket having more data in buffer. Option nomoredata_on_close disabled, so continuing.");
200 _gras_lastly_selected_socket = NULL;
203 /* FIXME: Issue an event when the socket is closed */
204 XBT_DEBUG("sockets pointer before %p", sockets);
206 /* FIXME: Cannot get the dynar mutex, because it can be already locked */
207 // _xbt_dynar_foreach(sockets,cursor,sock_iter) {
208 for (cursor = 0; cursor < xbt_dynar_length(sockets); cursor++) {
209 _xbt_dynar_cursor_get(sockets, cursor, &sock_iter);
210 if (sock == sock_iter) {
211 XBT_DEBUG("remove sock cursor %d dize %lu\n", cursor,
212 xbt_dynar_length(sockets));
213 xbt_dynar_cursor_rm(sockets, &cursor);
214 if (sock->plugin->socket_close)
215 (*sock->plugin->socket_close) (sock);
217 /* free the memory */
224 ("Ignoring request to free an unknown socket (%p). Execution stack:",
226 xbt_backtrace_display_current();
232 * Creating procdata for this module
234 static void *gras_trp_procdata_new(void)
236 gras_trp_procdata_t res = xbt_new(s_gras_trp_procdata_t, 1);
238 res->name = xbt_strdup("gras_trp");
240 res->sockets = xbt_dynar_new_sync(sizeof(xbt_socket_t *), NULL);
247 * Freeing procdata for this module
249 static void gras_trp_procdata_free(void *data)
251 gras_trp_procdata_t res = (gras_trp_procdata_t) data;
253 xbt_dynar_free(&(res->sockets));
258 void gras_trp_socketset_dump(const char *name)
260 gras_trp_procdata_t procdata =
261 (gras_trp_procdata_t) gras_libdata_by_id(gras_trp_libdata_id);
266 XBT_INFO("** Dump the socket set %s", name);
267 xbt_dynar_foreach(procdata->sockets, it, s) {
268 XBT_INFO(" %p -> %s:%d %s",
269 s, xbt_socket_peer_name(s), xbt_socket_peer_port(s),
270 s->valid ? "(valid)" : "(peer dead)");
272 XBT_INFO("** End of socket set %s", name);
276 * Module registration
278 int gras_trp_libdata_id;
279 void gras_trp_register()
281 gras_trp_libdata_id =
282 gras_procdata_add("gras_trp", gras_trp_procdata_new,
283 gras_trp_procdata_free);
286 int gras_os_myport(void)
288 return ((gras_trp_procdata_t)
289 gras_libdata_by_id(gras_trp_libdata_id))->myport;