src/xcalls/x_close.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 <misc/debug.h>
00013 #include <misc/errno.h>
00014 #include <core/tx.h>
00015 #include <core/config.h>
00016 #include <core/koa.h>
00017 #include <core/buffer.h>
00018 #include <core/stats.h>
00019 #include <libc/syscalls.h>
00020 #include <core/txdesc.h>
00021 #include <xcalls/xcalls.h>
00022 
00023 
00024 typedef struct x_close_commit_args_s x_close_commit_args_t;
00025 
00026 struct x_close_commit_args_s {
00027         int       fd;
00028         txc_koa_t *koa;
00029 };
00030 
00031 
00032 static
00033 void
00034 x_close_commit(void *args, int *result)
00035 {
00036         int                   local_errno = 0; 
00037         x_close_commit_args_t *myargs = (x_close_commit_args_t *) args;
00038         txc_koamgr_t          *koamgr;
00039         txc_result_t          xret;
00040 
00041         koamgr = txc_koa_get_koamgr(myargs->koa);
00042         txc_koa_lock_alias_cache(koamgr);
00043         txc_koa_lock_fd(koamgr, myargs->fd);
00044         xret = txc_koa_detach_fd(myargs->koa, myargs->fd, 0);
00045         if (xret == TXC_R_SUCCESS) {
00046                 if (txc_libc_close(myargs->fd) < 0) {
00047                         local_errno = errno;
00048                 }       
00049         } else {
00050                 local_errno = EBADF;
00051 
00052         }
00053         txc_koa_unlock_fd(koamgr, myargs->fd);
00054         txc_koa_unlock_alias_cache(koamgr);
00055         if (result) {
00056                 *result = local_errno;
00057         }
00058 }
00059 
00060 
00073 int
00074 XCALL_DEF(x_close)(int fildes, int *result) 
00075 {
00076         txc_tx_t              *txd;
00077         txc_koamgr_t          *koamgr = txc_g_koamgr;
00078         txc_koa_t             *koa;
00079         txc_sentinel_t        *sentinel;
00080         txc_result_t          xret;
00081         int                   ret;
00082         x_close_commit_args_t *args_commit; 
00083         int                   local_result = 0;
00084 
00085         txd = txc_tx_get_txd();
00086 
00087         switch(txc_tx_get_xactstate(txd)) {
00088                 case TXC_XACTSTATE_TRANSACTIONAL_RETRYABLE:
00089                         txc_koa_lock_fd(koamgr, fildes);
00090                         xret = txc_koa_lookup_fd2koa(koamgr, fildes, &koa);
00091                         if (xret == TXC_R_FAILURE) {
00092                                 /* 
00093                                  * The KOA mapped to the file descriptor has gone. Report
00094                                  * this error as invalid file descriptor.
00095                                  */
00096                                 txc_koa_unlock_fd(koamgr, fildes);
00097                                 local_result = EBADF;
00098                                 ret = -1;
00099                                 goto done;
00100                         }
00101 
00102                         sentinel = txc_koa_get_sentinel(koa);
00103                         xret = txc_sentinel_tryacquire(txd, sentinel, TXC_SENTINEL_ACQUIREONRETRY);
00104                         if (xret == TXC_R_BUSYSENTINEL) {
00105                                 txc_koa_unlock_fd(koamgr, fildes);
00106                                 txc_tx_abort_transaction(txd, TXC_ABORTREASON_BUSYSENTINEL);
00107                                 TXC_INTERNALERROR("Never gets here. Transaction abort failed.\n");
00108                         } else {
00109                                 txc_koa_unlock_fd(koamgr, fildes);
00110                         }
00111 
00112                         args_commit = (x_close_commit_args_t *)
00113                                       txc_buffer_linear_malloc(txd->buffer_linear, 
00114                                                                sizeof(x_close_commit_args_t));
00115                         if (args_commit == NULL) {
00116                                 TXC_INTERNALERROR("Allocation failed. Linear buffer out of space.\n");
00117                         }
00118                         args_commit->koa = koa;
00119                         args_commit->fd = fildes;
00120 
00121                         txc_tx_register_commit_action(txd, x_close_commit, 
00122                                                       (void *) args_commit, result,
00123                                                       TXC_KOA_DESTROY_COMMIT_ACTION_ORDER);
00124 
00125                         txc_koa_unlock_fd(koamgr, fildes);
00126                         ret = 0;
00127                         txc_stats_txstat_increment(txd, XCALL, x_close, 1);
00128                         break;
00129                 case TXC_XACTSTATE_TRANSACTIONAL_IRREVOCABLE:
00130                 case TXC_XACTSTATE_NONTRANSACTIONAL:
00131                         /* 
00132                          * Even if xCalls don't provide transactional properties when called
00133                          * outside of a transaction, we still need to destroy a KOA. Thus we
00134                          * still need to properly synchronize accesses to internal data
00135                          * structures.
00136                          */
00137                         txc_koa_lock_alias_cache(koamgr);
00138                         if ((ret = txc_libc_close(fildes)) < 0) { 
00139                                 txc_koa_unlock_alias_cache(koamgr);
00140                                 local_result = errno;
00141                                 goto done;
00142                         }
00143                         xret = txc_koa_lookup_fd2koa(koamgr, fildes, &koa);
00144                         txc_koa_detach_fd(koa, fildes, 1);
00145                         txc_koa_unlock_alias_cache(koamgr);
00146                         ret = fildes;
00147         }       
00148 done:
00149         if (result) {
00150                 *result = local_result;
00151         }
00152         return ret;
00153 }

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