rpcdb.cc

00001 /* 
00002    EyeDB Object Database Management System
00003    Copyright (C) 1994-2008 SYSRA
00004    
00005    EyeDB is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009    
00010    EyeDB is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014    
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with this library; if not, write to the Free Software
00017    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA 
00018 */
00019 
00020 /*
00021    Author: Eric Viara <viara@sysra.com>
00022 */
00023 
00024 #include "eyedbconfig.h"
00025 
00026 #include <stdlib.h>
00027 #include <stdio.h>
00028 #include <pthread.h>
00029 
00030 #include <eyedblib/rpc.h>
00031 #include <eyedblib/rpcdb.h>
00032 #include <eyedblib/rpc_be.h>
00033 #include <eyedblib/rpcdb_be.h>
00034 
00035 static pthread_mutex_t mp_dbhinfo, mp_sem;
00036 
00037 void rpcDB_mutexInit(void)
00038 {
00039   pthread_mutexattr_t mattr;
00040 
00041   pthread_mutexattr_init(&mattr);
00042   pthread_mutex_init(&mp_dbhinfo, &mattr);
00043   pthread_mutex_init(&mp_sem, &mattr);
00044 }
00045 
00046 int
00047 rpcDB_getDbhId()
00048 {
00049   /* THERE IS A GREAT PROBLEM, DUE TO CONCURRENCE IN LOCAL ACCESS ! */
00050   /* this dbhid is used both for XID and RHDBID */
00051 #if 1
00052   static int dbhid = 1000;
00053   return dbhid++;
00054 #else
00055   static int dbhid = 1;
00056   /* this kludge ensure that there is no concurency problem */
00057   /* BUT THE PROBLEM IS THAT the transaction XID are not the
00058      same in the server and in the client in case of a local opening! */
00059   return 65536 + rpc_getpid() + dbhid++;
00060 #endif
00061 }
00062 
00063 #define MAX_DBHINFO 128
00064 
00065 static rpcDB_DbHandleInfo *rpcDB_dbhInfo[MAX_DBHINFO];
00066 
00067 rpcDB_DbHandleInfo *
00068 rpcDB_dbhinfoNew(int id)
00069 {
00070   int i;
00071 
00072   pthread_mutex_lock(&mp_dbhinfo);
00073   for (i = 0; i < MAX_DBHINFO; i++)
00074     if (!rpcDB_dbhInfo[i])
00075       {
00076         rpcDB_dbhInfo[i] = (rpcDB_DbHandleInfo *)calloc(sizeof(rpcDB_DbHandleInfo), 1);
00077         rpcDB_dbhInfo[i]->id = id;
00078         rpcDB_dbhInfo[i]->refcnt = 1;
00079         pthread_mutex_unlock(&mp_dbhinfo);
00080         return rpcDB_dbhInfo[i];
00081       }
00082   pthread_mutex_unlock(&mp_dbhinfo);
00083   return 0;
00084 }
00085 
00086 rpcDB_DbHandleInfo *
00087 rpcDB_dbhinfoGet(int id)
00088 {
00089   int i;
00090 
00091   pthread_mutex_lock(&mp_dbhinfo);
00092   for (i = 0; i < MAX_DBHINFO; i++)
00093     if (rpcDB_dbhInfo[i] && rpcDB_dbhInfo[i]->id == id)
00094       {
00095         rpcDB_dbhInfo[i]->refcnt++;
00096 #ifdef TRACE
00097         printf("incrementing dbhinfo %d\n", rpcDB_dbhInfo[i]->refcnt);
00098 #endif
00099         pthread_mutex_unlock(&mp_dbhinfo);
00100         return rpcDB_dbhInfo[i];
00101       }
00102   pthread_mutex_unlock(&mp_dbhinfo);
00103   return 0;
00104 }
00105 
00106 rpcDB_ClientInfo *
00107 rpcDB_clientInfoGet(rpc_ClientId clientid)
00108 {
00109   static rpcDB_ClientInfo rpcDB_clientInfo;
00110 
00111   return &rpcDB_clientInfo;
00112 }
00113 
00114 void
00115 rpcDB_clientDbhDelete(rpcDB_DbHandleClientInfo *dbhclientinfo)
00116 {
00117   pthread_mutex_lock(&mp_dbhinfo);
00118 
00119   if (--dbhclientinfo->dbhinfo->refcnt == 0)
00120     {
00121       int i;
00122       for (i = 0; i < MAX_DBHINFO; i++)
00123         if (rpcDB_dbhInfo[i] == dbhclientinfo->dbhinfo)
00124           {
00125             free(rpcDB_dbhInfo[i]);
00126             rpcDB_dbhInfo[i] = 0;
00127             break;
00128           }
00129     }
00130   free(dbhclientinfo);
00131   pthread_mutex_unlock(&mp_dbhinfo);
00132 }
00133 
00134 int
00135 rpcDB_clientDbhSet(rpc_ClientId clientid, rpc_Boolean local, int flags, rpcDB_DbHandleInfo *dbhinfo, void *dbh)
00136 {
00137   int i;
00138   register rpcDB_ClientInfo *ci = rpcDB_clientInfoGet(clientid);
00139 
00140   for (i = 0; i < RPCDB_MAX_DBH; i++)
00141     if (!ci->dbhclientinfo[i])
00142       {
00143         rpcDB_DbHandleClientInfo *dbhclientinfo = (rpcDB_DbHandleClientInfo *)
00144           calloc(sizeof(rpcDB_DbHandleClientInfo), 1);
00145         dbhclientinfo->dbhinfo = dbhinfo;
00146         dbhclientinfo->local = local;
00147         dbhclientinfo->dbh = dbh;
00148         dbhclientinfo->flags = flags;
00149         ci->dbhclientinfo[i] = dbhclientinfo;
00150         return dbhinfo->id;
00151       }
00152   return 0;
00153 }
00154 
00155 rpcDB_DbHandleClientInfo *
00156 rpcDB_clientDbhGet(rpc_ClientId clientid, int id)
00157 {
00158   register rpcDB_ClientInfo *ci = rpcDB_clientInfoGet(clientid);
00159   rpcDB_DbHandleClientInfo *dbhclientinfo;
00160   int i;
00161 
00162   for (i = 0; i < RPCDB_MAX_DBH; i++)
00163     if ((dbhclientinfo = ci->dbhclientinfo[i]) &&
00164         dbhclientinfo->dbhinfo->id == id)
00165       return dbhclientinfo;
00166   return 0;
00167 }
00168 
00169 void
00170 rpcDB_lock()
00171 {
00172   pthread_mutex_lock(&mp_dbhinfo);
00173 }
00174 
00175 void
00176 rpcDB_unlock()
00177 {
00178   pthread_mutex_unlock(&mp_dbhinfo);
00179 }
00180 
00181 rpcDB_DbHandleInfo *
00182 rpcDB_open_simple_realize(rpc_Server *server, int id)
00183 {
00184   rpcDB_DbHandleInfo *dbhinfo;
00185 
00186   dbhinfo = rpcDB_dbhinfoGet(id);
00187 
00188   if (!dbhinfo)
00189     dbhinfo = rpcDB_dbhinfoNew(id);
00190 
00191   return dbhinfo;
00192 }
00193 
00194 static void
00195 rpcDB_sem_rm(int semid)
00196 {
00197 #ifdef TRACE
00198   printf("removing %d\n", semid);
00199 #endif
00200 #ifndef LOCKMTX
00201   if (semid && sem_rm(semid) < 0)
00202     fprintf(stderr, "warning removing semaphore %d\n", semid);
00203 #endif
00204 }
00205 
00206 rpc_Boolean
00207 rpcDB_close_do(rpc_Server *server, rpcDB_DbHandleClientInfo **pdbhclientinfo,
00208                void *(*close)(rpcDB_DbHandleClientInfo *),
00209                void **pstatus)
00210 {
00211   rpcDB_DbHandleClientInfo *dbhclientinfo = *pdbhclientinfo;
00212   *pstatus = 0;
00213 
00214   if (!dbhclientinfo)
00215     return rpc_False;
00216   else
00217     {
00218 #ifdef TRACE
00219       printf("rpcDB_close_do %p\n", dbhclientinfo->dbh);
00220 #endif
00221       rpcDB_lock();
00222       if (dbhclientinfo->dbhinfo->refcnt == 1 /* || abortProgram */)
00223         {
00224 #ifndef LOCKMTX
00225           rpcDB_sem_rm(dbhclientinfo->dbhinfo->ldbctx.semid[0]);
00226           rpcDB_sem_rm(dbhclientinfo->dbhinfo->ldbctx.semid[1]);
00227 #endif
00228         }
00229       
00230       rpcDB_unlock();
00231       *pstatus = (*close)(dbhclientinfo);
00232 
00233       rpcDB_clientDbhDelete(dbhclientinfo);
00234 
00235       *pdbhclientinfo = 0;
00236     }
00237 
00238   return rpc_True;
00239 }
00240 
00241 rpc_Boolean
00242 rpcDB_close_realize(rpc_Server *server, rpc_ClientId clientid, int dbid,
00243                     void *(*close)(rpcDB_DbHandleClientInfo *),
00244                     void **pstatus)
00245 {
00246   register rpcDB_ClientInfo *ci = rpcDB_clientInfoGet(clientid);
00247   rpcDB_DbHandleClientInfo *dbhclientinfo;
00248   int i;
00249 
00250 #ifdef TRACE
00251   printf("rpcDB_close_realize(())\n");
00252 #endif
00253   *pstatus = 0;
00254   for (i = 0; i < RPCDB_MAX_DBH; i++)
00255     if ((dbhclientinfo = ci->dbhclientinfo[i]) &&
00256         (dbhclientinfo->dbhinfo->id == dbid || !dbid))
00257       return rpcDB_close_do(server, &ci->dbhclientinfo[i], close, pstatus);
00258 
00259   return rpc_False;
00260 }

Generated on Mon Dec 22 18:16:07 2008 for eyedb by  doxygen 1.5.3