Ticket #49699: patch-semaphore-implementation.diff

File patch-semaphore-implementation.diff, 9.9 KB (added by ramundsen85, 8 years ago)

semaphore implementation adopted from osxfuse sshfs

  • Makefile.am

    diff -ENwbur orig/Makefile.am new/Makefile.am
    old new  
    66if FUSE_OPT_COMPAT
    77sshfs_SOURCES += compat/fuse_opt.c compat/fuse_opt.h
    88endif
     9if DARWIN_COMPAT
     10sshfs_SOURCES += compat/darwin_compat.c compat/darwin_compat.h
     11endif
    912
    1013sshfs_LDADD = $(SSHFS_LIBS)
    1114sshfs_CFLAGS = $(SSHFS_CFLAGS)
  • compat/darwin_compat.c

    diff -ENwbur orig/compat/darwin_compat.c new/compat/darwin_compat.c
    old new  
     1/*
     2 * Copyright (c) 2006-2008 Amit Singh/Google Inc.
     3 * Copyright (c) 2012 Anatol Pomozov
     4 * Copyright (c) 2011-2013 Benjamin Fleischer
     5 */
     6
     7#include "darwin_compat.h"
     8
     9#include <assert.h>
     10#include <errno.h>
     11#include <sys/types.h>
     12
     13/*
     14 * Semaphore implementation based on:
     15 *
     16 * Copyright (C) 2000,02 Free Software Foundation, Inc.
     17 * This file is part of the GNU C Library.
     18 * Written by Ga<EB>l Le Mignot <address@hidden>
     19 *
     20 * The GNU C Library is free software; you can redistribute it and/or
     21 * modify it under the terms of the GNU Library General Public License as
     22 * published by the Free Software Foundation; either version 2 of the
     23 * License, or (at your option) any later version.
     24 *
     25 * The GNU C Library is distributed in the hope that it will be useful,
     26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     28 * Library General Public License for more details.
     29 *
     30 * You should have received a copy of the GNU Library General Public
     31 * License along with the GNU C Library; see the file COPYING.LIB.  If not,
     32 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
     33 * Boston, MA 02111-1307, USA.
     34 */
     35
     36/* Semaphores */
     37
     38#define __SEM_ID_NONE  ((int)0x0)
     39#define __SEM_ID_LOCAL ((int)0xcafef00d)
     40
     41/* http://www.opengroup.org/onlinepubs/007908799/xsh/sem_init.html */
     42int
     43darwin_sem_init(darwin_sem_t *sem, int pshared, unsigned int value)
     44{
     45    if (pshared) {
     46        errno = ENOSYS;
     47        return -1;
     48    }
     49
     50    sem->id = __SEM_ID_NONE;
     51
     52    if (pthread_cond_init(&sem->__data.local.count_cond, NULL)) {
     53        goto cond_init_fail;
     54    }
     55
     56    if (pthread_mutex_init(&sem->__data.local.count_lock, NULL)) {
     57        goto mutex_init_fail;
     58    }
     59
     60    sem->__data.local.count = value;
     61    sem->id = __SEM_ID_LOCAL;
     62
     63    return 0;
     64
     65mutex_init_fail:
     66
     67    pthread_cond_destroy(&sem->__data.local.count_cond);
     68
     69cond_init_fail:
     70
     71    return -1;
     72}
     73
     74/* http://www.opengroup.org/onlinepubs/007908799/xsh/sem_destroy.html */
     75int
     76darwin_sem_destroy(darwin_sem_t *sem)
     77{
     78    int res = 0;
     79
     80    pthread_mutex_lock(&sem->__data.local.count_lock);
     81
     82    sem->id = __SEM_ID_NONE;
     83    pthread_cond_broadcast(&sem->__data.local.count_cond);
     84
     85    if (pthread_cond_destroy(&sem->__data.local.count_cond)) {
     86        res = -1;
     87    }
     88
     89    pthread_mutex_unlock(&sem->__data.local.count_lock);
     90
     91    if (pthread_mutex_destroy(&sem->__data.local.count_lock)) {
     92        res = -1;
     93    }
     94
     95    return res;
     96}
     97
     98int
     99darwin_sem_getvalue(darwin_sem_t *sem, unsigned int *sval)
     100{
     101    int res = 0;
     102
     103    pthread_mutex_lock(&sem->__data.local.count_lock);
     104
     105    if (sem->id != __SEM_ID_LOCAL) {
     106        res = -1;
     107        errno = EINVAL;
     108    } else {
     109        *sval = sem->__data.local.count;
     110    }
     111
     112    pthread_mutex_unlock(&sem->__data.local.count_lock);
     113
     114    return res;
     115}
     116
     117/* http://www.opengroup.org/onlinepubs/007908799/xsh/sem_post.html */
     118int
     119darwin_sem_post(darwin_sem_t *sem)
     120{
     121    int res = 0;
     122
     123    pthread_mutex_lock(&sem->__data.local.count_lock);
     124
     125    if (sem->id != __SEM_ID_LOCAL) {
     126        res = -1;
     127        errno = EINVAL;
     128    } else if (sem->__data.local.count < DARWIN_SEM_VALUE_MAX) {
     129        sem->__data.local.count++;
     130        if (sem->__data.local.count == 1) {
     131            pthread_cond_signal(&sem->__data.local.count_cond);
     132        }
     133    } else {
     134        errno = ERANGE;
     135        res = -1;
     136    }
     137
     138    pthread_mutex_unlock(&sem->__data.local.count_lock);
     139
     140    return res;
     141}
     142
     143/* http://www.opengroup.org/onlinepubs/009695399/functions/sem_timedwait.html */
     144int
     145darwin_sem_timedwait(darwin_sem_t *sem, const struct timespec *abs_timeout)
     146{
     147    int res = 0;
     148
     149    if (abs_timeout &&
     150        (abs_timeout->tv_nsec < 0 || abs_timeout->tv_nsec >= 1000000000)) {
     151        errno = EINVAL;
     152        return -1;
     153    }
     154
     155    pthread_cleanup_push((void(*)(void*))&pthread_mutex_unlock,
     156                 &sem->__data.local.count_lock);
     157
     158    pthread_mutex_lock(&sem->__data.local.count_lock);
     159
     160    if (sem->id != __SEM_ID_LOCAL) {
     161        errno = EINVAL;
     162        res = -1;
     163    } else {
     164        if (!sem->__data.local.count) {
     165            res = pthread_cond_timedwait(&sem->__data.local.count_cond,
     166                             &sem->__data.local.count_lock,
     167                             abs_timeout);
     168        }
     169        if (res) {
     170            assert(res == ETIMEDOUT);
     171            res = -1;
     172            errno = ETIMEDOUT;
     173        } else if (sem->id != __SEM_ID_LOCAL) {
     174            res = -1;
     175            errno = EINVAL;
     176        } else {
     177            sem->__data.local.count--;
     178        }
     179    }
     180
     181    pthread_cleanup_pop(1);
     182
     183    return res;
     184}
     185
     186/* http://www.opengroup.org/onlinepubs/007908799/xsh/sem_trywait.html */
     187int
     188darwin_sem_trywait(darwin_sem_t *sem)
     189{
     190    int res = 0;
     191
     192    pthread_mutex_lock(&sem->__data.local.count_lock);
     193
     194    if (sem->id != __SEM_ID_LOCAL) {
     195        res = -1;
     196        errno = EINVAL;
     197    } else if (sem->__data.local.count) {
     198        sem->__data.local.count--;
     199    } else {
     200        res = -1;
     201        errno = EAGAIN;
     202    }
     203
     204    pthread_mutex_unlock (&sem->__data.local.count_lock);
     205
     206    return res;
     207}
     208
     209/* http://www.opengroup.org/onlinepubs/007908799/xsh/sem_wait.html */
     210int
     211darwin_sem_wait(darwin_sem_t *sem)
     212{
     213    int res = 0;
     214
     215    pthread_cleanup_push((void(*)(void*))&pthread_mutex_unlock,
     216                 &sem->__data.local.count_lock);
     217
     218    pthread_mutex_lock(&sem->__data.local.count_lock);
     219
     220    if (sem->id != __SEM_ID_LOCAL) {
     221        errno = EINVAL;
     222        res = -1;
     223    } else {
     224        if (!sem->__data.local.count) {
     225            pthread_cond_wait(&sem->__data.local.count_cond,
     226                      &sem->__data.local.count_lock);
     227            if (!sem->__data.local.count) {
     228                /* spurious wakeup, assume it is an interruption */
     229                res = -1;
     230                errno = EINTR;
     231                goto out;
     232            }
     233        }
     234        if (sem->id != __SEM_ID_LOCAL) {
     235            res = -1;
     236            errno = EINVAL;
     237        } else {
     238            sem->__data.local.count--;
     239        }
     240    }
     241
     242out:
     243    pthread_cleanup_pop(1);
     244
     245    return res;
     246}
  • compat/darwin_compat.h

    diff -ENwbur orig/compat/darwin_compat.h new/compat/darwin_compat.h
    old new  
     1/*
     2 * Copyright (c) 2006-2008 Amit Singh/Google Inc.
     3 * Copyright (c) 2011-2013 Benjamin Fleischer
     4 */
     5
     6#ifndef _DARWIN_COMPAT_
     7#define _DARWIN_COMPAT_
     8
     9#include <pthread.h>
     10
     11/* Semaphores */
     12
     13typedef struct darwin_sem {
     14    int id;
     15    union {
     16        struct
     17        {
     18            unsigned int    count;
     19            pthread_mutex_t count_lock;
     20            pthread_cond_t  count_cond;
     21        } local;
     22    } __data;
     23} darwin_sem_t;
     24
     25#define DARWIN_SEM_VALUE_MAX ((int32_t)32767)
     26
     27int darwin_sem_init(darwin_sem_t *sem, int pshared, unsigned int value);
     28int darwin_sem_destroy(darwin_sem_t *sem);
     29int darwin_sem_getvalue(darwin_sem_t *sem, unsigned int *value);
     30int darwin_sem_post(darwin_sem_t *sem);
     31int darwin_sem_timedwait(darwin_sem_t *sem, const struct timespec *abs_timeout);
     32int darwin_sem_trywait(darwin_sem_t *sem);
     33int darwin_sem_wait(darwin_sem_t *sem);
     34
     35/* Caller must not include <semaphore.h> */
     36
     37typedef darwin_sem_t sem_t;
     38
     39#define sem_init(s, p, v)   darwin_sem_init(s, p, v)
     40#define sem_destroy(s)      darwin_sem_destroy(s)
     41#define sem_getvalue(s, v)  darwin_sem_getvalue(s, v)
     42#define sem_post(s)         darwin_sem_post(s)
     43#define sem_timedwait(s, t) darwin_sem_timedwait(s, t)
     44#define sem_trywait(s)      darwin_sem_trywait(s)
     45#define sem_wait(s)         darwin_sem_wait(s)
     46
     47#define SEM_VALUE_MAX       DARWIN_SEM_VALUE_MAX
     48
     49#endif /* _DARWIN_COMPAT_ */
  • configure.ac

    diff -ENwbur orig/configure.ac new/configure.ac
    old new  
    11AC_INIT(sshfs-fuse, 2.5)
     2AC_CANONICAL_TARGET
    23AM_INIT_AUTOMAKE
    34AM_CONFIG_HEADER(config.h)
    45
     
    1112AC_SUBST(sshnodelay_libs)
    1213LIBS=
    1314
     15case $target_os in
     16      *linux*)  arch=linux;;
     17      *netbsd*) arch=netbsd;;
     18      *bsd*)    arch=bsd;;
     19      *darwin*) arch=darwin;;
     20      *)                arch=unknown;;
     21esac
     22
    1423AC_ARG_ENABLE(sshnodelay,
    1524        [  --disable-sshnodelay    Don't compile NODELAY workaround for ssh])
    1625
     
    4352LIBS="$LIBS $SSHFS_LIBS"
    4453AC_CHECK_FUNC([fuse_opt_parse], [have_fuse_opt_parse=yes])
    4554LIBS="$oldlibs"
    46 if test "$have_fuse_opt_parse" = no; then
     55if test "$have_fuse_opt_parse" = no -o "$arch" = darwin; then
    4756        CFLAGS="$CFLAGS -Icompat"
    4857fi
    4958AM_CONDITIONAL(FUSE_OPT_COMPAT, test "$have_fuse_opt_parse" = no)
     59AM_CONDITIONAL(DARWIN_COMPAT, test "$arch" = darwin)
    5060
    5161AC_CONFIG_FILES([Makefile])
    5262AC_OUTPUT
  • sshfs.c

    diff -ENwbur orig/sshfs.c new/sshfs.c
    old new  
    2020#include <string.h>
    2121#include <stdint.h>
    2222#include <errno.h>
     23#ifndef __APPLE__
    2324#include <semaphore.h>
     25#endif
    2426#include <pthread.h>
    2527#include <netdb.h>
    2628#include <signal.h>
     
    3840#include <pwd.h>
    3941#include <grp.h>
    4042#include <limits.h>
     43#ifdef __APPLE__
     44#  include <libgen.h>
     45#  include <darwin_compat.h>
     46#endif
    4147
    4248#include "cache.h"
    4349