- Timestamp:
- Nov 21, 2017, 10:24:14 AM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/prototype-v0/zoo-project/zoo-kernel/service_internal.c
r839 r854 39 39 40 40 #define ERROR_MSG_MAX_LENGTH 1024 41 42 /** 43 * Lock a file for read, write and upload. 44 * @param conf the main configuration maps 45 * @param filename the file to lock 46 * @param mode define access: 'r' for read, 'w' for write 47 * @return a new zooLock structure on sucess, NULL on failure 48 */ 49 struct zooLock* lockFile(maps* conf,const char* filename,const char mode){ 50 struct stat f_status; 51 int itn=0; 52 int s; 53 struct zooLock* myLock=(struct zooLock*)malloc(sizeof(struct flock)+sizeof(FILE*)+sizeof(char*)); 54 int len=6; 55 char *template="%s.lock"; 56 int res=-1; 57 retryLockFile: 58 myLock->filename=(char*)malloc((strlen(filename)+len)*sizeof(char)); 59 sprintf(myLock->filename,"%s.lock",filename); 60 s=stat(myLock->filename, &f_status); 61 if(s==0 && mode!='r'){ 62 if(itn<ZOO_LOCK_MAX_RETRY){ 63 itn++; 64 sleep(5); 65 free(myLock->filename); 66 goto retryLockFile; 67 }else{ 68 free(myLock->filename); 69 free(myLock); 70 return NULL; 71 } 72 }else{ 73 char local_mode[3]; 74 memset(local_mode,0,3); 75 if(mode=='w') 76 sprintf(local_mode,"%c+",mode); 77 else 78 sprintf(local_mode,"%c",mode); 79 myLock->lockfile=fopen(myLock->filename,local_mode); 80 char tmp[512]; 81 sprintf(tmp,"%d",getpid()); 82 if(myLock->lockfile==NULL){ 83 myLock->lockfile=fopen(myLock->filename,"w+"); 84 fwrite(tmp,sizeof(char),strlen(tmp),myLock->lockfile); 85 fflush(myLock->lockfile); 86 fclose(myLock->lockfile); 87 myLock->lockfile=fopen(myLock->filename,local_mode); 88 }/*else 89 fprintf(stderr,"%s %d %d\n",__FILE__,__LINE__,(myLock->lockfile==NULL));*/ 90 if(mode!='r'){ 91 fwrite(tmp,sizeof(char),strlen(tmp),myLock->lockfile); 92 fflush(myLock->lockfile); 93 } 94 int cnt=0; 95 if(mode=='r'){ 96 myLock->lock.l_type = F_RDLCK; 97 }else 98 myLock->lock.l_type = F_WRLCK; 99 myLock->lock.l_whence = 0; 100 myLock->lock.l_start = 0; 101 myLock->lock.l_len = strlen(tmp)*sizeof(char); 102 while (true) { 103 if((res=fcntl(fileno(myLock->lockfile), F_SETLK, &(myLock->lock)))==-1 && 104 (errno==EAGAIN || errno==EACCES)){ 105 if(cnt >= ZOO_LOCK_MAX_RETRY){ 106 char message[51]; 107 sprintf(message,"Unable to get the lock after %d attempts.\n",cnt); 108 setMapInMaps(conf,"lenv","message",message); 109 fclose(myLock->lockfile); 110 free(myLock->filename); 111 free(myLock); 112 return NULL; 113 } 114 fprintf(stderr,"(%d) Wait for lock on %s, tried %d times ... \n",getpid(),myLock->filename,cnt); 115 fflush(stderr); 116 sleep(1); 117 cnt++; 118 }else 119 break; 120 } 121 if(res<0){ 122 char *tmp; 123 if(errno==EBADF) 124 tmp="Either: the filedes argument is invalid; you requested a read lock but the filedes is not open for read access; or, you requested a write lock but the filedes is not open for write access."; 125 else 126 if(errno==EINVAL) 127 tmp="Either the lockp argument doesn’t specify valid lock information, or the file associated with filedes doesn’t support locks."; 128 else 129 tmp="The system has run out of file lock resources; there are already too many file locks in place."; 130 fprintf(stderr,"Unable to get the lock on %s due to the following error: %s\n",myLock->filename,tmp); 131 return NULL; 132 } 133 return myLock; 134 } 135 } 136 137 /** 138 * Remove a lock. 139 * @param conf the main configuration maps 140 * @param s the zooLock structure 141 * @return 0 on success, -1 on failure. 142 */ 143 int unlockFile(maps* conf,struct zooLock* s){ 144 int res=-1; 145 if(s!=NULL){ 146 s->lock.l_type = F_UNLCK; 147 res=fcntl(fileno(s->lockfile), F_SETLK, &s->lock); 148 if(res==-1) 149 return res; 150 // Check if there is any process locking a file and delete the lock if not. 151 s->lock.l_type = F_WRLCK; 152 if(fcntl(fileno(s->lockfile), F_GETLK, &s->lock)!=-1 && s->lock.l_type == F_UNLCK){ 153 unlink(s->filename); 154 } 155 fclose(s->lockfile); 156 free(s->filename); 157 free(s); 158 } 159 return res; 160 } 161 41 162 #ifndef RELY_ON_DB 42 163 #include <dirent.h>
Note: See TracChangeset
for help on using the changeset viewer.