void adquireReadLock(Bloqueio *bloqueio){ sem_adquire(&bloqueio->mutex, 0); bloqueio->leitor_count++; // Quando for o primeiro leitor, diz a todos os outros // que o banco de dados está sendo lido if (bloqueio->leitor_count == 1) sem_adquire(&bloqueio->db, 0); sem_libera(&bloqueio->mutex, 0); }
void liberaReadLock(Bloqueio *bloqueio){ sem_adquire(&bloqueio->mutex, 0); bloqueio->leitor_count--; // Quando é o último leitor, diz a todos os outros // que o banco de dados não está sendo lido if (bloqueio->leitor_count == 0) sem_libera(&bloqueio->db, 0); sem_libera(&bloqueio->mutex, 0); }
void adquireWriteLock(Bloqueio *bloqueio){ sem_adquire(&bloqueio->db, 0); }
ret_t cherokee_spawner_spawn (cherokee_buffer_t *binary, cherokee_buffer_t *user, uid_t uid, gid_t gid, int env_inherited, char **envp, cherokee_logger_writer_t *error_writer, pid_t *pid_ret) { #ifdef HAVE_SYSV_SEMAPHORES char **n; int *pid_shm; int pid_prev; int k; int phase; int envs = 0; cherokee_buffer_t tmp = CHEROKEE_BUF_INIT; #define ALIGN4(buf) \ while (buf.len & 0x3) { \ cherokee_buffer_add_char (&buf, '\0'); \ } /* Check it's initialized */ if ((! _active) || (cherokee_spawn_shared.mem == NULL)) { TRACE (ENTRIES, "Spawner is not active. Returning: %s\n", binary->buf); return ret_deny; } /* Lock the monitor mutex */ k = CHEROKEE_MUTEX_TRY_LOCK (&spawning_mutex); if (k) { return ret_eagain; } /* Build the string * The first character of each block is a mark. */ cherokee_buffer_ensure_size (&tmp, SPAWN_SHARED_LEN); /* 1.- Executable */ phase = 0xF0; cherokee_buffer_add (&tmp, (char *)&phase, sizeof(int)); cherokee_buffer_add (&tmp, (char *)&binary->len, sizeof(int)); cherokee_buffer_add_buffer (&tmp, binary); cherokee_buffer_add_char (&tmp, '\0'); ALIGN4 (tmp); /* 2.- UID & GID */ phase = 0xF1; cherokee_buffer_add (&tmp, (char *)&phase, sizeof(int)); cherokee_buffer_add (&tmp, (char *)&user->len, sizeof(int)); cherokee_buffer_add_buffer (&tmp, user); cherokee_buffer_add_char (&tmp, '\0'); ALIGN4(tmp); cherokee_buffer_add (&tmp, (char *)&uid, sizeof(uid_t)); cherokee_buffer_add (&tmp, (char *)&gid, sizeof(gid_t)); /* 3.- Environment */ phase = 0xF2; cherokee_buffer_add (&tmp, (char *)&phase, sizeof(int)); for (n=envp; *n; n++) { envs ++; } cherokee_buffer_add (&tmp, (char *)&env_inherited, sizeof(int)); cherokee_buffer_add (&tmp, (char *)&envs, sizeof(int)); for (n=envp; *n; n++) { int len = strlen(*n); cherokee_buffer_add (&tmp, (char *)&len, sizeof(int)); cherokee_buffer_add (&tmp, *n, len); cherokee_buffer_add_char (&tmp, '\0'); ALIGN4(tmp); } /* 4.- Error log */ phase = 0xF3; cherokee_buffer_add (&tmp, (char *)&phase, sizeof(int)); write_logger (&tmp, error_writer); ALIGN4 (tmp); /* 5.- PID (will be rewritten by the other side) */ phase = 0xF4; cherokee_buffer_add (&tmp, (char *)&phase, sizeof(int)); pid_shm = (int *) (((char *)cherokee_spawn_shared.mem) + tmp.len); k = *pid_ret; pid_prev = *pid_ret; cherokee_buffer_add (&tmp, (char *)&k, sizeof(int)); /* Copy it to the shared memory */ if (unlikely (tmp.len > SPAWN_SHARED_LEN)) { goto error; } memcpy (cherokee_spawn_shared.mem, tmp.buf, tmp.len); cherokee_buffer_mrproper (&tmp); /* Wake up the spawning thread */ sem_unlock (cherokee_spawn_sem, SEM_LAUNCH_START); /* Wait for the PID */ sem_adquire (cherokee_spawn_sem, SEM_LAUNCH_READY); if (*pid_shm == -1) { TRACE(ENTRIES, "Could not get the PID of: '%s'\n", binary->buf); goto error; } if (*pid_shm == pid_prev) { TRACE(ENTRIES, "Could not the new PID, previously it was %d\n", pid_prev); goto error; } TRACE(ENTRIES, "Successfully launched PID=%d\n", *pid_shm); *pid_ret = *pid_shm; CHEROKEE_MUTEX_UNLOCK (&spawning_mutex); return ret_ok; error: CHEROKEE_MUTEX_UNLOCK (&spawning_mutex); return ret_error; #else return ret_not_found; #endif /* HAVE_SYSV_SEMAPHORES */ }