src/xcalls/x_socket.c

Go to the documentation of this file.
00001 
00007 #include <fcntl.h>
00008 #include <unistd.h>
00009 #include <errno.h>
00010 #include <string.h>
00011 #include <stdlib.h>
00012 #include <sys/socket.h>
00013 #include <misc/debug.h>
00014 #include <misc/errno.h>
00015 #include <core/tx.h>
00016 #include <core/config.h>
00017 #include <core/koa.h>
00018 #include <core/buffer.h>
00019 #include <core/txdesc.h>
00020 #include <core/stats.h>
00021 #include <libc/syscalls.h>
00022 #include <xcalls/xcalls.h>
00023 
00024 
00025 typedef struct x_socket_undo_args_s x_socket_undo_args_t;
00026 
00027 struct x_socket_undo_args_s {
00028         int       fd;
00029         txc_koa_t *koa;
00030 };
00031 
00032 
00033 static
00034 void
00035 x_socket_undo(void *args, int *result)
00036 {
00037         int                local_errno = 0; 
00038         x_socket_undo_args_t *myargs = (x_socket_undo_args_t *) args;
00039         txc_koamgr_t       *koamgr;
00040 
00041         koamgr = txc_koa_get_koamgr(myargs->koa);
00042         txc_koa_lock_fd(koamgr, myargs->fd);
00043         txc_koa_detach_fd(myargs->koa, myargs->fd, 0);
00044         if (txc_libc_close(myargs->fd) < 0) {
00045                 local_errno = errno;
00046         }       
00047         txc_koa_unlock_fd(koamgr, myargs->fd);
00048         if (result) {
00049                 *result = local_errno;
00050         }
00051 }
00052 
00053 
00075 int 
00076 XCALL_DEF(x_socket)(int domain, int type, int protocol, int *result) 
00077 {
00078         int                fildes;
00079         txc_tx_t           *txd;
00080         txc_koamgr_t       *koamgr = txc_g_koamgr;
00081         txc_koa_t          *koa;
00082         txc_sentinel_t     *sentinel;
00083         txc_result_t       xret;
00084         int                ret;
00085         x_socket_undo_args_t *args_undo; 
00086         int                local_result = 0;
00087         int                koa_type;
00088 
00089         txd = txc_tx_get_txd();
00090 
00091         switch(type) {
00092                 case SOCK_DGRAM:
00093                         koa_type = TXC_KOA_IS_SOCK_DGRAM;
00094                         break;
00095                 case SOCK_STREAM:
00096                         local_result = EINVAL;
00097                         ret = -1;
00098                         goto done;
00099         }               
00100 
00101         switch(txc_tx_get_xactstate(txd)) {
00102                 case TXC_XACTSTATE_TRANSACTIONAL_RETRYABLE:
00103                         if ((ret = fildes = txc_libc_socket(domain, type, protocol)) < 0) { 
00104                                 local_result = errno;
00105                                 goto done;
00106                         }
00107                         txc_koa_create(koamgr, &koa, koa_type, NULL); 
00108                         txc_koa_lock_fd(koamgr, fildes);
00109                         txc_koa_attach_fd(koa, fildes, 0);
00110                         sentinel = txc_koa_get_sentinel(koa);
00111                         xret = txc_sentinel_tryacquire(txd, sentinel, 0);
00112                         if (xret != TXC_R_SUCCESS) {
00113                                 TXC_INTERNALERROR("Cannot acquire the sentinel of the KOA I've just created!\n");
00114                         }
00115         
00116                         args_undo = (x_socket_undo_args_t *)
00117                                     txc_buffer_linear_malloc(txd->buffer_linear, 
00118                                                              sizeof(x_socket_undo_args_t));
00119                         if (args_undo == NULL) {
00120                                 TXC_INTERNALERROR("Allocation failed. Linear buffer out of space.\n");
00121                         }
00122                         args_undo->koa = koa;
00123                         args_undo->fd = fildes;
00124 
00125                         txc_tx_register_undo_action  (txd, x_socket_undo, 
00126                                                       (void *) args_undo, result,
00127                                                       TXC_KOA_CREATE_UNDO_ACTION_ORDER);
00128 
00129                         txc_koa_unlock_fd(koamgr, fildes);
00130                         ret = fildes;
00131                         txc_stats_txstat_increment(txd, XCALL, x_socket, 1);
00132                         break;
00133                 case TXC_XACTSTATE_TRANSACTIONAL_IRREVOCABLE:
00134                 case TXC_XACTSTATE_NONTRANSACTIONAL:
00135                         /* 
00136                          * Even if xCalls don't provide transactional properties when called
00137                          * outside of a transaction, we still need to create a KOA and assign
00138                          * a sentinel to be used later by any transactional xCalls. Thus we
00139                          * still need to properly synchronize accesses to internal data
00140                          * structures.
00141                          */
00142                         if ((ret = fildes = txc_libc_socket(domain, type, protocol)) < 0) { 
00143                                 local_result = errno;
00144                                 goto done;
00145                         }
00146                         txc_koa_create(koamgr, &koa, koa_type, NULL); 
00147                         txc_koa_lock_fd(koamgr, fildes);
00148                         txc_koa_attach_fd(koa, fildes, 0);
00149                         txc_koa_unlock_fd(koamgr, fildes);
00150                         ret = fildes;
00151         }
00152 done:
00153         if (result) {
00154                 *result = local_result;
00155         }
00156         return ret;
00157 }

Generated on Wed Dec 9 20:32:39 2009 for xCalls by  doxygen 1.4.7