Ignore:
Timestamp:
May 7, 2019, 2:17:08 PM (5 years ago)
Author:
djay
Message:

Merge prototype-v0 branch in trunk

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/zoo-project/zoo-kernel/service_internal.c

    r889 r917  
    22 * Author : Gérald FENOY
    33 *
    4  * Copyright (c) 2009-2015 GeoLabs SARL
     4 * Copyright (c) 2009-2018 GeoLabs SARL
    55 *
    66 * Permission is hereby granted, free of charge, to any person obtaining a copy
     
    3131#include "service_internal.h"
    3232
    33 #ifndef TRUE
    34 #define TRUE 1
    35 #endif
    36 #ifndef FALSE
    37 #define FALSE -1
    38 #endif
    39 
     33#ifdef WIN32
     34// ref. https://docs.microsoft.com/en-us/windows/desktop/fileio/locking-and-unlocking-byte-ranges-in-files
     35__inline int fcntl(int fd, int cmd, ...)
     36{
     37  va_list a;
     38  va_start(a, cmd);
     39  switch(cmd)
     40    {
     41    case F_SETLK:
     42      {
     43        HANDLE h = (HANDLE)_get_osfhandle(fd);
     44        struct flock* l= va_arg(a, struct flock*);
     45        OVERLAPPED sOverlapped;
     46        sOverlapped.Offset = 0;
     47        sOverlapped.OffsetHigh = 0;
     48        switch(l->l_type)
     49          {
     50          case F_RDLCK:
     51            {
     52              if (!LockFileEx(h, LOCKFILE_FAIL_IMMEDIATELY, 0, l->l_len, 0, &sOverlapped))
     53                {
     54                  _set_errno(GetLastError() == ERROR_LOCK_VIOLATION ? EAGAIN : EBADF);
     55                  return -1;
     56                }
     57            }
     58            break;
     59          case F_WRLCK:
     60            {
     61              if (!LockFileEx(h, LOCKFILE_FAIL_IMMEDIATELY|LOCKFILE_EXCLUSIVE_LOCK, 0, l->l_len, 0, &sOverlapped))
     62                {
     63                  _set_errno(GetLastError() == ERROR_LOCK_VIOLATION ? EAGAIN : EBADF);
     64                  return -1;
     65                }
     66            }
     67            break;
     68          case F_UNLCK:
     69            {
     70              UnlockFileEx(h, 0, l->l_len, 0, &sOverlapped);
     71            }
     72            break;
     73          default:
     74            _set_errno(ENOTSUP);
     75            return -1;
     76          }
     77      }
     78      break;
     79    default:
     80      _set_errno(ENOTSUP);
     81      return -1;
     82    }
     83  return 0;
     84}
     85#endif
    4086#define ERROR_MSG_MAX_LENGTH 1024
     87
     88/**
     89 * Lock a file for read, write and upload.
     90 * @param conf the main configuration maps
     91 * @param filename the file to lock
     92 * @param mode define access: 'r' for read, 'w' for write
     93 * @return a new zooLock structure on sucess, NULL on failure
     94 */
     95struct zooLock* lockFile(maps* conf,const char* filename,const char mode){
     96  struct stat f_status;
     97  int itn=0;
     98  int s;
     99  struct zooLock* myLock=(struct zooLock*)malloc(sizeof(struct flock)+sizeof(FILE*)+sizeof(char*));
     100  int len=6;
     101  char *myTemplate="%s.lock";
     102  int res=-1;
     103 retryLockFile:
     104  myLock->filename=(char*)malloc((strlen(filename)+len)*sizeof(char));
     105  sprintf(myLock->filename,myTemplate,filename);
     106  s=stat(myLock->filename, &f_status);
     107  if(s==0 && mode!='r'){
     108    if(itn<ZOO_LOCK_MAX_RETRY){
     109      itn++;
     110#ifdef DEBUG
     111      fprintf(stderr,"(%d) Wait for write lock on %s, tried %d times (sleep) ... \n",zGetpid(),myLock->filename,itn);
     112      fflush(stderr);
     113#endif
     114      zSleep(5);
     115      free(myLock->filename);
     116      goto retryLockFile;
     117    }else{
     118      free(myLock->filename);
     119      free(myLock);
     120      return NULL;
     121    }
     122  }else{
     123    char local_mode[3];
     124    memset(local_mode,0,3);
     125    if(mode=='w')
     126      sprintf(local_mode,"%c+",mode);
     127    else
     128      sprintf(local_mode,"%c",mode);
     129    myLock->lockfile=fopen(myLock->filename,local_mode);
     130    char tmp[512];
     131    sprintf(tmp,"%d",zGetpid());
     132    if(myLock->lockfile==NULL){
     133      myLock->lockfile=fopen(myLock->filename,"w+");
     134      fwrite(tmp,sizeof(char),strlen(tmp),myLock->lockfile);
     135      fflush(myLock->lockfile);
     136      fclose(myLock->lockfile);
     137      myLock->lockfile=fopen(myLock->filename,local_mode);
     138    }/*else
     139       fprintf(stderr,"%s %d %d\n",__FILE__,__LINE__,(myLock->lockfile==NULL));*/
     140    if(mode!='r'){
     141      fwrite(tmp,sizeof(char),strlen(tmp),myLock->lockfile);
     142      fflush(myLock->lockfile);
     143    }
     144    int cnt=0;
     145    if(mode=='r'){
     146      myLock->lock.l_type = F_RDLCK;
     147    }else
     148      myLock->lock.l_type = F_WRLCK;
     149    myLock->lock.l_whence = 0;
     150    myLock->lock.l_start = 0;
     151    myLock->lock.l_len = strlen(tmp)*sizeof(char);
     152    while (true) {
     153      if((res=fcntl(fileno(myLock->lockfile), F_SETLK, &(myLock->lock)))==-1 &&
     154         (errno==EAGAIN || errno==EACCES)){
     155          if(cnt >= ZOO_LOCK_MAX_RETRY){
     156            char message[51];     
     157            sprintf(message,"Unable to get the lock after %d attempts.\n",cnt);
     158            setMapInMaps(conf,"lenv","message",message);
     159            fclose(myLock->lockfile);
     160            free(myLock->filename);
     161            free(myLock);
     162            return NULL;
     163          }
     164#ifdef DEBUG
     165          fprintf(stderr,"(%d) Wait for lock on  %s, tried %d times ... \n",zGetpid(),myLock->filename,cnt);
     166          fflush(stderr);
     167#endif
     168          zSleep(1);
     169          cnt++;
     170        }else
     171           break;
     172    }
     173    if(res<0){
     174      char *tmp;
     175      if(errno==EBADF)
     176        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.";
     177      else
     178        if(errno==EINVAL)
     179          tmp="Either the lockp argument doesn’t specify valid lock information, or the file associated with filedes doesn’t support locks.";
     180        else
     181          tmp="The system has run out of file lock resources; there are already too many file locks in place.";
     182#ifdef DEBUG
     183      fprintf(stderr,"Unable to get the lock on %s due to the following error: %s\n",myLock->filename,tmp);
     184#endif
     185      return NULL;
     186    }
     187    return myLock;
     188  }
     189}
     190
     191/**
     192 * Remove a lock.
     193 * @param conf the main configuration maps
     194 * @param s the zooLock structure
     195 * @return 0 on success, -1 on failure.
     196 */
     197int unlockFile(maps* conf,struct zooLock* s){
     198  int res=-1;
     199  if(s!=NULL){
     200    s->lock.l_type = F_UNLCK;
     201    res=fcntl(fileno(s->lockfile), F_SETLK, &s->lock);
     202    if(res==-1)
     203      return res;
     204    fclose(s->lockfile);
     205#ifndef WIN32
     206    // Check if there is any process locking a file and delete the lock if not.
     207    s->lock.l_type = F_WRLCK;
     208    if(fcntl(fileno(s->lockfile), F_GETLK, &s->lock)!=-1 && s->lock.l_type == F_UNLCK){
     209#endif
     210      zUnlink(s->filename);
     211#ifndef WIN32
     212    }
     213#endif
     214    free(s->filename);
     215    free(s);
     216  }
     217  return res;
     218}
     219
    41220#ifndef RELY_ON_DB
    42 #include <dirent.h>
     221#include "dirent.h"
    43222
    44223/**
     
    148327
    149328    //FILE* f0 = fopen (fileName, "r");
    150         // knut: open file in binary mode to avoid conversion of line endings (yielding extra bytes) on Windows platforms
    151         FILE* f0 = fopen(fileName, "rb");
     329    // knut: open file in binary mode to avoid conversion of line endings (yielding extra bytes) on Windows platforms
     330    FILE* f0 = fopen(fileName, "rb");
    152331    if(f0!=NULL){
    153332      fseek (f0, 0, SEEK_END);
     
    162341        free(stat);
    163342      }
    164 
    165343      return tmps1;
    166344    }
     
    250428                     * sizeof (char));
    251429  sprintf (fbkpid, "%s/%s.status", r_inputs->value, usid->value);
    252   unlink(fbkpid);
     430  zUnlink(fbkpid);
    253431  free(fbkpid);
    254432}
     
    510688            }
    511689        }
     690        setMapInMaps(conf,"lenv","semaphore","Created");
    512691    } else if (errno == EEXIST) { /* someone else got it first */
    513692        int ready = 0;
     
    529708              fprintf(stderr,"Retry to access the semaphore later ...\n");
    530709#endif
    531               zSleep(1);
     710              zSleep(1000);
    532711            }
    533712        }
     
    540719          return -1;
    541720        }
     721        setMapInMaps(conf,"lenv","semaphore","Acquired");
    542722    } else {
    543723        return sem_id; /* error, check errno */
     
    739919}
    740920
     921/**
     922 * Check if file exists in specified folder
     923 *
     924 * @param dir the folder in which to search for file
     925 * @param name the name of the file (not full path)
     926 * @return a character string with the full path [dir/name], or NULL if the file does not exist
     927 *
     928 * @attention Caller is responsible for applying free() to the returned pointer
     929 */
     930char* file_exists(const char* dir, const char* name) {
     931        const char* d = (dir != NULL ? dir : ".");
     932        if (name != NULL) {
     933                size_t length = strlen(d) + strlen(name) + 2; // including file separator and \0 character
     934                char* path = (char*)calloc(length, sizeof(char));
     935                snprintf(path, length, "%s/%s", d, name);
     936
     937                struct stat buffer;
     938                if (stat(path, &buffer) != 0) {
     939                        free(path);
     940                        path = NULL;
     941                }
     942                return path;
     943        }
     944        else {
     945                return NULL;
     946        }
     947}
Note: See TracChangeset for help on using the changeset viewer.

Search

Context Navigation

ZOO Sponsors

http://www.zoo-project.org/trac/chrome/site/img/geolabs-logo.pnghttp://www.zoo-project.org/trac/chrome/site/img/neogeo-logo.png http://www.zoo-project.org/trac/chrome/site/img/apptech-logo.png http://www.zoo-project.org/trac/chrome/site/img/3liz-logo.png http://www.zoo-project.org/trac/chrome/site/img/gateway-logo.png

Become a sponsor !

Knowledge partners

http://www.zoo-project.org/trac/chrome/site/img/ocu-logo.png http://www.zoo-project.org/trac/chrome/site/img/gucas-logo.png http://www.zoo-project.org/trac/chrome/site/img/polimi-logo.png http://www.zoo-project.org/trac/chrome/site/img/fem-logo.png http://www.zoo-project.org/trac/chrome/site/img/supsi-logo.png http://www.zoo-project.org/trac/chrome/site/img/cumtb-logo.png

Become a knowledge partner

Related links

http://zoo-project.org/img/ogclogo.png http://zoo-project.org/img/osgeologo.png