💾 Archived View for gmi.noulin.net › gitRepositories › filelock › file › filelock.c.gmi captured on 2024-09-29 at 00:31:31. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-01-29)
-=-=-=-=-=-=-
filelock.c (4809B)
1 // 2 // 3 // 4 5 #include "libsheepyObject.h" 6 #include "filelock.h" 7 #include "filelockInternal.h" 8 9 #define internal static 10 11 #include <stdlib.h> 12 #include <string.h> 13 #include <stdio.h> 14 #include <sys/stat.h> // open 15 #include <fcntl.h> // open 16 #include <unistd.h> // close 17 18 void initiateFilelock(filelockt *self); 19 void registerMethodsFilelock(filelockFunctionst *f); 20 void initiateAllocateFilelock(filelockt **self); 21 void finalizeFilelock(void); 22 filelockt* allocFilelock(const char *filepath); 23 internal void freeFilelock(filelockt *self); 24 internal void terminateFilelock(filelockt **self); 25 internal char* toStringFilelock(filelockt *self); 26 internal filelockt* duplicateFilelock(filelockt *self); 27 internal void smashFilelock(filelockt **self); 28 internal void finishFilelock(filelockt **self); 29 internal void setDelaysFilelock (filelockt *self, f32 timeout, f32 delay); 30 internal void logFilelock (filelockt *self); 31 internal bool acquireFilelock (filelockt *self); 32 internal void releaseFilelock (filelockt *self); 33 internal void setFilelock (filelockt *self, const char *filepath); 34 internal const char* getFilelock(filelockt *self); 35 36 void initiateFilelock(filelockt *self) { 37 38 self->type = "filelock"; 39 if (!filelockF) { 40 filelockF = malloc(sizeof(filelockFunctionst)); 41 registerMethodsFilelock(filelockF); 42 pErrorNot0(atexit(finalizeFilelock)); 43 } 44 self->f = filelockF; 45 46 self->isLocked = false; 47 self->lockfile = NULL; 48 self->filename = NULL; 49 self->timeout = 10; 50 self->delay = 0.05; 51 self->fd = -1; 52 } 53 54 void registerMethodsFilelock(filelockFunctionst *f) { 55 56 f->free = freeFilelock; 57 f->terminate = terminateFilelock; 58 f->toString = toStringFilelock; 59 f->duplicate = duplicateFilelock; 60 f->smash = smashFilelock; 61 f->finish = finishFilelock; 62 f->setDelays = setDelaysFilelock; 63 f->log = logFilelock; 64 f->acquire = acquireFilelock; 65 f->release = releaseFilelock; 66 f->set = setFilelock; 67 f->get = getFilelock; 68 } 69 70 void initiateAllocateFilelock(filelockt **self) { 71 72 if (self) { 73 (*self) = malloc(sizeof(filelockt)); 74 if (*self) { 75 initiateFilelock(*self); 76 } 77 } 78 } 79 80 void finalizeFilelock(void) { 81 82 if (filelockF) { 83 free(filelockF); 84 filelockF = NULL; 85 } 86 } 87 88 filelockt* allocFilelock(const char *filepath) { 89 filelockt *r = NULL; 90 91 initiateAllocateFilelock(&r); 92 if (filepath) { 93 r->filename = strdup(filepath); 94 r->lockfile = formatS("%s.lock", filepath); 95 } 96 return(r); 97 } 98 99 100 internal void freeFilelock(filelockt *self) { 101 102 freeManyS(self->lockfile, self->filename); 103 return; 104 } 105 106 internal void terminateFilelock(filelockt **self) { 107 108 freeFilelock(*self); 109 free(*self); 110 *self = NULL; 111 } 112 113 114 internal char* toStringFilelock(filelockt *self) { 115 116 return(strdup("filelock")); 117 } 118 119 internal filelockt* duplicateFilelock(filelockt *self) { 120 121 createAllocateFilelock(dup); 122 dup->isLocked = self->isLocked; 123 dup->filename = dupS(self->filename); 124 dup->lockfile = dupS(self->lockfile); 125 dup->timeout = self->timeout; 126 dup->delay = self->delay; 127 dup->fd = self->fd; 128 return(dup); 129 } 130 131 internal void smashFilelock(filelockt **self) { 132 133 finishFilelock(self); 134 } 135 136 internal void finishFilelock(filelockt **self) { 137 138 free(*self); 139 *self = NULL; 140 } 141 142 internal void setDelaysFilelock (filelockt *self, f32 timeout, f32 delay) { 143 144 self->timeout = timeout; 145 self->delay = delay; 146 } 147 148 internal void logFilelock (filelockt *self) { 149 char *s = toStringG(self->isLocked); 150 printf("isLocked: %s\n", s); 151 free(s); 152 printf("filename: %s\n", self->filename); 153 printf("timeout: %f\n", self->timeout); 154 printf("delay: %f\n", self->delay); 155 printf("lockfile: %s\n", self->lockfile); 156 } 157 158 internal bool acquireFilelock (filelockt *self) { 159 160 u64 startTime = getMonotonicTime(); 161 162 if (not self->lockfile) return false; 163 164 if (not self->isLocked) { 165 while (true) { 166 self->fd = open(self->lockfile, O_CREAT|O_EXCL|O_RDWR); 167 if (self->fd != -1) break; 168 if ((getMonotonicTime() - startTime) > (self->timeout*1E9)) return false; 169 nanoSleep(self->delay*1E9); 170 } 171 self->isLocked = true; 172 return true; 173 } 174 return false; 175 } 176 177 internal void releaseFilelock (filelockt *self) { 178 179 if (self->isLocked) { 180 close(self->fd); 181 rmAll(self->lockfile); 182 self->isLocked = false; 183 } 184 } 185 186 internal void setFilelock(filelockt *self, const char *filepath) { 187 if (not filepath) return; 188 if (self->filename) { 189 freeManyS(self->filename, self->lockfile); 190 } 191 self->filename = strdup(filepath); 192 self->lockfile = formatS("%s.lock", filepath); 193 } 194 195 internal const char* getFilelock(filelockt *self) { 196 return self->filename; 197 } 198 199 bool checkLibsheepyVersionFilelock(const char *currentLibsheepyVersion) { 200 return eqG(currentLibsheepyVersion, LIBSHEEPY_VERSION); 201 } 202