1141cc406Sopenharmony_ci/* 2141cc406Sopenharmony_ci Mutex implementation for SnapScan backend 3141cc406Sopenharmony_ci 4141cc406Sopenharmony_ci Copyright (C) 2000, 2004 Henrik Johansson, Oliver Schwartz 5141cc406Sopenharmony_ci 6141cc406Sopenharmony_ci This program is free software; you can redistribute it and/or 7141cc406Sopenharmony_ci modify it under the terms of the GNU General Public License as 8141cc406Sopenharmony_ci published by the Free Software Foundation; either version 2 of the 9141cc406Sopenharmony_ci License, or (at your option) any later version. 10141cc406Sopenharmony_ci 11141cc406Sopenharmony_ci This program is distributed in the hope that it will be useful, but 12141cc406Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 13141cc406Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14141cc406Sopenharmony_ci General Public License for more details. 15141cc406Sopenharmony_ci 16141cc406Sopenharmony_ci You should have received a copy of the GNU General Public License 17141cc406Sopenharmony_ci along with this program. If not, see <https://www.gnu.org/licenses/>. 18141cc406Sopenharmony_ci 19141cc406Sopenharmony_ci As a special exception, the authors of SANE give permission for 20141cc406Sopenharmony_ci additional uses of the libraries contained in this release of SANE. 21141cc406Sopenharmony_ci 22141cc406Sopenharmony_ci The exception is that, if you link a SANE library with other files 23141cc406Sopenharmony_ci to produce an executable, this does not by itself cause the 24141cc406Sopenharmony_ci resulting executable to be covered by the GNU General Public 25141cc406Sopenharmony_ci License. Your use of that executable is in no way restricted on 26141cc406Sopenharmony_ci account of linking the SANE library code into it. 27141cc406Sopenharmony_ci 28141cc406Sopenharmony_ci This exception does not, however, invalidate any other reasons why 29141cc406Sopenharmony_ci the executable file might be covered by the GNU General Public 30141cc406Sopenharmony_ci License. 31141cc406Sopenharmony_ci 32141cc406Sopenharmony_ci If you submit changes to SANE to the maintainers to be included in 33141cc406Sopenharmony_ci a subsequent release, you agree by submitting the changes that 34141cc406Sopenharmony_ci those changes may be distributed with this exception intact. 35141cc406Sopenharmony_ci 36141cc406Sopenharmony_ci If you write modifications of your own for SANE, it is your choice 37141cc406Sopenharmony_ci whether to permit this exception to apply to your modifications. 38141cc406Sopenharmony_ci If you do not wish that, delete this exception notice.*/ 39141cc406Sopenharmony_ci 40141cc406Sopenharmony_ci#if defined __BEOS__ 41141cc406Sopenharmony_ci 42141cc406Sopenharmony_ci#include <OS.h> 43141cc406Sopenharmony_ci#define snapscan_mutex_t sem_id 44141cc406Sopenharmony_ci 45141cc406Sopenharmony_cistatic int snapscani_mutex_open(snapscan_mutex_t* a_sem, const char* dev __sane_unused__) 46141cc406Sopenharmony_ci{ 47141cc406Sopenharmony_ci *a_sem = create_sem(1, "snapscan_mutex"); 48141cc406Sopenharmony_ci return 1; 49141cc406Sopenharmony_ci} 50141cc406Sopenharmony_ci 51141cc406Sopenharmony_cistatic void snapscani_mutex_close(snapscan_mutex_t* a_sem) 52141cc406Sopenharmony_ci{ 53141cc406Sopenharmony_ci delete_sem(*a_sem); 54141cc406Sopenharmony_ci} 55141cc406Sopenharmony_ci 56141cc406Sopenharmony_cistatic void snapscani_mutex_lock(snapscan_mutex_t* a_sem) 57141cc406Sopenharmony_ci{ 58141cc406Sopenharmony_ci acquire_sem(*a_sem); 59141cc406Sopenharmony_ci} 60141cc406Sopenharmony_ci 61141cc406Sopenharmony_cistatic void snapscani_mutex_unlock(snapscan_mutex_t* a_sem) 62141cc406Sopenharmony_ci{ 63141cc406Sopenharmony_ci release_sem(*a_sem); 64141cc406Sopenharmony_ci} 65141cc406Sopenharmony_ci 66141cc406Sopenharmony_ci 67141cc406Sopenharmony_ci 68141cc406Sopenharmony_ci#elif defined USE_PTHREAD || defined HAVE_OS2_H 69141cc406Sopenharmony_ci 70141cc406Sopenharmony_ci#include <pthread.h> 71141cc406Sopenharmony_ci#define snapscan_mutex_t pthread_mutex_t 72141cc406Sopenharmony_ci 73141cc406Sopenharmony_cistatic int snapscani_mutex_open(snapscan_mutex_t* sem_id, const char* dev __sane_unused__) 74141cc406Sopenharmony_ci{ 75141cc406Sopenharmony_ci pthread_mutex_init(sem_id, NULL); 76141cc406Sopenharmony_ci return 1; 77141cc406Sopenharmony_ci} 78141cc406Sopenharmony_ci 79141cc406Sopenharmony_cistatic void snapscani_mutex_close(snapscan_mutex_t* sem_id) 80141cc406Sopenharmony_ci{ 81141cc406Sopenharmony_ci pthread_mutex_destroy(sem_id); 82141cc406Sopenharmony_ci} 83141cc406Sopenharmony_ci 84141cc406Sopenharmony_cistatic void snapscani_mutex_lock(snapscan_mutex_t* sem_id) 85141cc406Sopenharmony_ci{ 86141cc406Sopenharmony_ci pthread_mutex_lock(sem_id); 87141cc406Sopenharmony_ci} 88141cc406Sopenharmony_ci 89141cc406Sopenharmony_cistatic void snapscani_mutex_unlock(snapscan_mutex_t* sem_id) 90141cc406Sopenharmony_ci{ 91141cc406Sopenharmony_ci pthread_mutex_unlock(sem_id); 92141cc406Sopenharmony_ci} 93141cc406Sopenharmony_ci 94141cc406Sopenharmony_ci#else /* defined USE_PTHREAD || defined HAVE_OS2_H */ 95141cc406Sopenharmony_ci 96141cc406Sopenharmony_ci#include <sys/ipc.h> 97141cc406Sopenharmony_ci#include <sys/sem.h> 98141cc406Sopenharmony_ci#include <sys/types.h> 99141cc406Sopenharmony_ci#include <unistd.h> 100141cc406Sopenharmony_ci 101141cc406Sopenharmony_ci#define snapscan_mutex_t int 102141cc406Sopenharmony_ci 103141cc406Sopenharmony_ci/* check for union semun */ 104141cc406Sopenharmony_ci#if defined(HAVE_UNION_SEMUN) 105141cc406Sopenharmony_ci/* union semun is defined by including <sys/sem.h> */ 106141cc406Sopenharmony_ci#else 107141cc406Sopenharmony_ci/* according to X/OPEN we have to define it ourselves */ 108141cc406Sopenharmony_ciunion semun { 109141cc406Sopenharmony_ci int val; /* value for SETVAL */ 110141cc406Sopenharmony_ci struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */ 111141cc406Sopenharmony_ci unsigned short int *array; /* array for GETALL, SETALL */ 112141cc406Sopenharmony_ci struct seminfo *__buf; /* buffer for IPC_INFO */ 113141cc406Sopenharmony_ci}; 114141cc406Sopenharmony_ci#endif /* defined HAVE_UNION_SEMUN */ 115141cc406Sopenharmony_ci 116141cc406Sopenharmony_cistatic struct sembuf sem_wait = { 0, -1, 0 }; 117141cc406Sopenharmony_cistatic struct sembuf sem_signal = { 0, 1, 0 }; 118141cc406Sopenharmony_ci 119141cc406Sopenharmony_cistatic unsigned int snapscani_bernstein(const unsigned char* str) 120141cc406Sopenharmony_ci{ 121141cc406Sopenharmony_ci unsigned int hash = 5381; /* some arbitrary number */ 122141cc406Sopenharmony_ci int c; 123141cc406Sopenharmony_ci 124141cc406Sopenharmony_ci while (*str) 125141cc406Sopenharmony_ci { 126141cc406Sopenharmony_ci c = *str++; 127141cc406Sopenharmony_ci hash = ((hash << 5) + hash) + c; 128141cc406Sopenharmony_ci } 129141cc406Sopenharmony_ci return hash; 130141cc406Sopenharmony_ci} 131141cc406Sopenharmony_ci 132141cc406Sopenharmony_cistatic int snapscani_mutex_open(snapscan_mutex_t* sem_id, const char* dev) 133141cc406Sopenharmony_ci{ 134141cc406Sopenharmony_ci static const char *me = "snapscani_mutex_open"; 135141cc406Sopenharmony_ci key_t ipc_key = -1; 136141cc406Sopenharmony_ci 137141cc406Sopenharmony_ci if (strstr(dev, "libusb:") == dev) 138141cc406Sopenharmony_ci { 139141cc406Sopenharmony_ci key_t ipc_key = (key_t) snapscani_bernstein((const unsigned char*) dev+7); 140141cc406Sopenharmony_ci DBG (DL_INFO, "%s: using IPC key 0x%08x for device %s\n", 141141cc406Sopenharmony_ci me, ipc_key, dev); 142141cc406Sopenharmony_ci } 143141cc406Sopenharmony_ci else 144141cc406Sopenharmony_ci { 145141cc406Sopenharmony_ci ipc_key = ftok(dev, 0x12); 146141cc406Sopenharmony_ci 147141cc406Sopenharmony_ci if (ipc_key == -1) 148141cc406Sopenharmony_ci { 149141cc406Sopenharmony_ci DBG (DL_MAJOR_ERROR, "%s: could not obtain IPC key for device %s: %s\n", me, dev, strerror(errno)); 150141cc406Sopenharmony_ci return 0; 151141cc406Sopenharmony_ci } 152141cc406Sopenharmony_ci } 153141cc406Sopenharmony_ci 154141cc406Sopenharmony_ci *sem_id = semget( ipc_key, 1, IPC_CREAT | 0660 ); 155141cc406Sopenharmony_ci if (*sem_id == -1) 156141cc406Sopenharmony_ci { 157141cc406Sopenharmony_ci DBG (DL_MAJOR_ERROR, "%s: semget failed: %s\n", me, strerror(errno)); 158141cc406Sopenharmony_ci return 0; 159141cc406Sopenharmony_ci } 160141cc406Sopenharmony_ci 161141cc406Sopenharmony_ci semop(*sem_id, &sem_signal, 1); 162141cc406Sopenharmony_ci return 1; 163141cc406Sopenharmony_ci} 164141cc406Sopenharmony_ci 165141cc406Sopenharmony_cistatic void snapscani_mutex_close(snapscan_mutex_t* sem_id) 166141cc406Sopenharmony_ci{ 167141cc406Sopenharmony_ci static union semun dummy_semun_arg; 168141cc406Sopenharmony_ci semctl(*sem_id, 0, IPC_RMID, dummy_semun_arg); 169141cc406Sopenharmony_ci} 170141cc406Sopenharmony_ci 171141cc406Sopenharmony_cistatic void snapscani_mutex_lock(snapscan_mutex_t* sem_id) 172141cc406Sopenharmony_ci{ 173141cc406Sopenharmony_ci semop(*sem_id, &sem_wait, 1); 174141cc406Sopenharmony_ci} 175141cc406Sopenharmony_ci 176141cc406Sopenharmony_cistatic void snapscani_mutex_unlock(snapscan_mutex_t* sem_id) 177141cc406Sopenharmony_ci{ 178141cc406Sopenharmony_ci semop(*sem_id, &sem_signal, 1); 179141cc406Sopenharmony_ci} 180141cc406Sopenharmony_ci 181141cc406Sopenharmony_ci#endif /* defined USE_PTHREAD || defined HAVE_OS2_H */ 182