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)
89 xbt_socket_t res = NULL;
92 for (port = minport; port < maxport; port++) {
94 res = gras_socket_server_ext(port, buf_size, measurement);
108 * @brief Opens a client socket to a remote host.
109 * @param host: who you want to connect to
110 * @param port: where you want to connect to on this host
111 * @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)
112 * @param measurement: whether this socket is meant to convey measurement (if you don't know, use 0 to exchange regular messages)
114 * In real life, you'll get a TCP socket.
117 gras_socket_client_ext(const char *host,
119 unsigned long int buf_size, int measurement)
121 xbt_trp_plugin_t trp;
124 trp = xbt_trp_plugin_get_by_name(gras_if_SG() ? "sg" : "tcp");
126 XBT_DEBUG("Create a client socket from plugin %s",
127 gras_if_RL()? "tcp" : "sg");
128 /* defaults settings */
129 xbt_socket_new_ext(0,
132 (buf_size > 0 ? buf_size : 32 * 1024),
135 /* plugin-specific */
137 (*trp->socket_client) (trp, host, port, sock);
143 xbt_dynar_push(((gras_trp_procdata_t)
144 gras_libdata_by_id(gras_trp_libdata_id))->sockets,
146 gras_msg_listener_awake();
151 * @brief Opens a server socket and make it ready to be listened to.
153 * In real life, you'll get a TCP socket.
155 xbt_socket_t gras_socket_server(unsigned short port)
157 return gras_socket_server_ext(port, 32 * 1024, 0);
160 /** @brief Opens a client socket to a remote host */
161 xbt_socket_t gras_socket_client(const char *host, unsigned short port)
163 return gras_socket_client_ext(host, port, 0, 0);
166 /** @brief Opens a client socket to a remote host specified as '\a host:\a port' */
167 xbt_socket_t gras_socket_client_from_string(const char *host)
169 xbt_peer_t p = xbt_peer_from_string(host);
170 xbt_socket_t res = gras_socket_client_ext(p->name, p->port, 0, 0);
175 void gras_socket_close_voidp(void *sock)
177 gras_socket_close((xbt_socket_t) sock);
180 /** \brief Close socket */
181 void gras_socket_close(xbt_socket_t sock)
183 if (--sock->refcount)
186 xbt_dynar_t sockets =
187 ((gras_trp_procdata_t)
188 gras_libdata_by_id(gras_trp_libdata_id))->sockets;
189 xbt_socket_t sock_iter = NULL;
193 XBT_VERB("Close %p", sock);
194 if (sock == _gras_lastly_selected_socket) {
195 xbt_assert(!gras_opt_trp_nomoredata_on_close || !sock->moredata,
196 "Closing a socket having more data in buffer while the nomoredata_on_close option is activated");
200 ("Closing a socket having more data in buffer. Option nomoredata_on_close disabled, so continuing.");
201 _gras_lastly_selected_socket = NULL;
204 /* FIXME: Issue an event when the socket is closed */
205 XBT_DEBUG("sockets pointer before %p", sockets);
207 /* FIXME: Cannot get the dynar mutex, because it can be already locked */
208 // _xbt_dynar_foreach(sockets,cursor,sock_iter) {
209 for (cursor = 0; cursor < xbt_dynar_length(sockets); cursor++) {
210 _xbt_dynar_cursor_get(sockets, cursor, &sock_iter);
211 if (sock == sock_iter) {
212 XBT_DEBUG("remove sock cursor %u dize %lu\n", cursor,
213 xbt_dynar_length(sockets));
214 xbt_dynar_cursor_rm(sockets, &cursor);
215 if (sock->plugin->socket_close)
216 (*sock->plugin->socket_close) (sock);
218 /* free the memory */
225 ("Ignoring request to free an unknown socket (%p). Execution stack:",
227 xbt_backtrace_display_current();
233 * Creating procdata for this module
235 static void *gras_trp_procdata_new(void)
237 gras_trp_procdata_t res = xbt_new(s_gras_trp_procdata_t, 1);
239 res->name = xbt_strdup("gras_trp");
241 res->sockets = xbt_dynar_new_sync(sizeof(xbt_socket_t *), NULL);
248 * Freeing procdata for this module
250 static void gras_trp_procdata_free(void *data)
252 gras_trp_procdata_t res = (gras_trp_procdata_t) data;
254 xbt_dynar_free(&(res->sockets));
259 void gras_trp_socketset_dump(const char *name)
261 gras_trp_procdata_t procdata =
262 (gras_trp_procdata_t) gras_libdata_by_id(gras_trp_libdata_id);
267 XBT_INFO("** Dump the socket set %s", name);
268 xbt_dynar_foreach(procdata->sockets, it, s) {
269 XBT_INFO(" %p -> %s:%d %s",
270 s, xbt_socket_peer_name(s), xbt_socket_peer_port(s),
271 s->valid ? "(valid)" : "(peer dead)");
273 XBT_INFO("** End of socket set %s", name);
277 * Module registration
279 int gras_trp_libdata_id;
280 void gras_trp_register()
282 gras_trp_libdata_id =
283 gras_procdata_add("gras_trp", gras_trp_procdata_new,
284 gras_trp_procdata_free);
287 int gras_os_myport(void)
289 return ((gras_trp_procdata_t)
290 gras_libdata_by_id(gras_trp_libdata_id))->myport;