💾 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

View Raw

More Information

⬅️ Previous capture (2023-01-29)

-=-=-=-=-=-=-

filelock

Log

Files

Refs

LICENSE

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