Do something while sem_wait in C - c

I am trying to avoid using sem_wait, and have something like:
"While waiting for semaphore, do something".
So then I found out about sem_getvalue which is supposed to return 0 in case of success.
So I initiate the semaphore with:
sem_init(&sem1, 0, 0);
And instead of
sem_wait(&sem1);
I need something like:
while(sem_getvalue(&sem1, 2) < 0){
printf("do this\n");
}
I have no problems with sem_wait, everything seems to function properly.
But with the second, I am getting Segmentation fault error during execution.
Any help is greatly appreciated, thanks!

You shouldn't use sem_getvalue for this since you are losing atomicity. Use sem_trywait for the task
for (;;) {
if (sem_trywait(&sem1)) {
if (errno != EAGAIN) {
/* handle error */
abort();
}
errno = 0;
printf("do this\n");
} else {
break;
}
}

sem_getvalue returns a status, and places the semaphore value at the pointer passed as the second parameter. You need to check the return status (which is zero when the function succeeds) and only then check the semaphore value, like this:
int sval1;
if (sem_getvalue(&sem1, &sval1) == 0 && sval1 < 0) {
...
}

Related

Getting result of exec*() from child process without waiting in any case (not using pipes and vfork())

I am working on custom wrappers for Unix-specific system calls now. And the last problem I met is about how to create a complete function for creating new processes with another image. And I want this function to return TRUE or FALSE. The last piece of this puzzle is how to get a result of exec*() from a child process without waiting for it's end in case of exec*()'s success. In other words, I need to get FAIL of SUCCESS result of exec*() quickly and continue execution of a parent process.
And I don't want to use vfork() and pipes.
My current results:
Using vfork() and a volatile variable for keeping result made their work.
static int QCreateProcess(char* args, ...)
{
if (processInfoStruct == NULL)
{
return Q_ERROR;
}
volatile int result = TRUE;
pid_t procHandle = vfork();
if (procHandle == 0)
{
char* argsToExec[2] = { args, NULL };
execv(argsToExec[0], argsToExec);
result = FALSE;
_exit(EXIT_FAILURE);
}
else if (procHandle == -1)
{
processInfoStruct->processHandle = NULL;
result = FALSE;
}
else
{
if (result == TRUE)
{
waitpid(procHandle, NULL, WNOHANG);
processInfoStruct->processHandle = procHandle;
}
else
{
processInfoStruct->processHandle = 0;
result = FALSE;
}
}
return result;
}
This code works and returns correct results.
How can this be implemented using fork() and waitpid() without the status variable (it won't work with fork() anyway...) and pipes? I tried to find solutions with different options for the last function (waitpid()), but a desired combination was not found.

accept call blocking thread termination

I'm having trouble terminating my server in my multithreaded program (one server, multiple clients).
When the variable global_var, which counts the number of currently connected clients, gets set to 0, the server should terminate, but it doesn't.
What I think is happening is since accept() is blocking , the code never reaches the break condition in main loop.
It's breaking correctly out of thread_func but then it blocks inside the while loop, just before the accept() call and after printing "Exiting thread_func".
volatile int finished = 0; // Gets set to 1 by catching SIGINT/SIGSTOP
int global_var = 0; // When it gets to 0, server should terminate
int server_fd;
void * thread_func(void* arg)
{
do_some_pre_stuff();
while(1)
{
if(!global_var)
{
close(server_fd);
finished = 1;
break;
}
if(recv(...) > 0)
{
do_more_stuff()
}
else
{
disconnect_client();
global_var--;
break;
}
}
free_more_ressources();
return NULL;
}
int main()
{
do_initial_stuff();
init_socket();
listen();
while (!finished)
{
if( (fd = accept(server_fd,...)) == -1)
exit(-1);
global_var++;
/* Some intermediate code */
if(!global_var)
break;
// Thread for the newly connected player
if(pthread_create(&thread_id[...], NULL, thread_func, (void*)some_arg)
exit(-1);
}
free_resources();
puts("Exiting thread_func");
}
I tried the advice listed here without success (except the pipe answer, not trying to mess with pipes).
I'm new to socket programming but what I tried so far looked correct but none of the solutions worked (including semaphores, pthread_cancel,etc)
PS: synchronization has been implemented, just omitted here for readability

Closing Libuv Loop Correctly During Initialization

I am initializing a loop in libuv, but if I need to return after I initialized the loop but before I have called uv_run, how do I correctly clean up all memory and file descriptors? Here is my example code, loop being uv_loop_t* and server being uv_tcp_t*:
if (uv_loop_init(loop) < 0) {
return -1;
}
if (uv_tcp_init(loop, server) < 0) {
// What code here?
return -1;
}
if (some_other_function() < 0) {
// What code here?
return -1;
}
uv_run(loop, UV_RUN_DEFAULT);
According to this question, I should stop, walk and run the loop, closing all the handles; but that assumes I'm already running the loop, which I'm not. I could just call uv_loop_close(loop), but that doesn't free the handles.
As mentioned in the link, you need to do something like this;
uv_loop_init(&loop);
uv_tcp_init(&loop, &server);
uv_walk(&loop,
[](uv_handle_t* handle, void* arg) {
printf("closing...%p\n", handle);
uv_close(handle, [](uv_handle_t* handle) {
printf("closed...%p\n", handle);
}
);
uv_run(&loop, UV_RUN_ONCE);
},
NULL);

Thread doesn't recognize change in a flag

I Work with couple of threads. all running as long as an exit_flag is set to false.
I Have specific thread that doesn't recognize the change in the flag, and therefor not ending and freeing up its resources, and i'm trying to understand why.
UPDATE: After debugging a bit with gdb, i can see that given 'enough time' the problematic thread does detects the flag change.
My conclusion from this is that not enough time passes for the thread to detect the change in normal run.
How can i 'delay' my main thread, long enough for all threads to detect the flag change, without having to JOIN them? (the use of exit_flag was in an intention NOT to join the threads, as i don't want to manage all threads id's for that - i'm just detaching each one of them, except the thread that handles input).
I've tried using sleep(5) in close_server() method, after the flag changing, with no luck
Notes:
Other threads that loop on the same flag does terminate succesfully
exit_flag declaration is: static volatile bool exit_flag
All threads are reading the flag, flag value is changed only in close_server() method i have (which does only that)
Data race that may occur when a thread reads the flag just before its changed, doesn't matter to me, as long as in the next iteration of the while loop it will read the correct value.
No error occurs in the thread itself (according to strerr & stdout which are 'clean' from error messages (for the errors i handle in the thread)
Ths situation also occurs even when commenting out the entire while((!exit_flag) && (remain_data > 0)) code block - so this is not a sendfile hanging issure
station_info_t struct:
typedef struct station_info {
int socket_fd;
int station_num;
} station_info_t;
Problematic thread code:
void * station_handler(void * arg_p)
{
status_type_t rs = SUCCESS;
station_info_t * info = (station_info_t *)arg_p;
int remain_data = 0;
int sent_bytes = 0;
int song_fd = 0;
off_t offset = 0;
FILE * fp = NULL;
struct stat file_stat;
/* validate station number for this handler */
if(info->station_num < 0) {
fprintf(stderr, "station_handler() station_num = %d, something's very wrong! exiting\n", info->station_num);
exit(EXIT_FAILURE);
}
/* Open the file to send, and get his stats */
fp = fopen(srv_params.songs_names[info->station_num], "r");
if(NULL == fp) {
close(info->socket_fd);
free(info);
error_and_exit("fopen() failed! errno = ", errno);
}
song_fd = fileno(fp);
if( fstat(song_fd, &file_stat) ) {
close(info->socket_fd);
fclose(fp);
free(info);
error_and_exit("fstat() failed! errno = ", errno);
}
/** Run as long as no exit procedure was initiated */
while( !exit_flag ) {
offset = 0;
remain_data = file_stat.st_size;
while( (!exit_flag) && (remain_data > 0) ) {
sent_bytes = sendfile(info->socket_fd, song_fd, &offset, SEND_BUF);
if(sent_bytes < 0 ) {
error_and_exit("sendfile() failed! errno = ", errno);
}
remain_data = remain_data - sent_bytes;
usleep(USLEEP_TIME);
}
}
printf("Station %d handle exited\n", info->station_num);
/* Free \ close all resources */
close(info->socket_fd);
fclose(fp);
free(info);
return NULL;
}
I'll be glad to get some help.
Thanks guys
Well, as stated by user362924 the main issue is that i don't join the threads in my main thread, therefore not allowing them enough time to exit.
A workaround to the matter, if for some reason one wouldn't want to join all threads and dynamically manage thread id's, is to use sleep command in the end of the main thread, for a couple of seconds.
of course this workaround is not good practice and not recommended (to anyone who gets here by google)

What would the source code of a try lock be?

So I think I understand the source code for a signal and a wait (the wait being a lock) but I am not sure how to implement a try lock.
Here is my code for a wait:
//if s->type is zero it is a binary semaphore type
if (s->type == 0)
{
// binary semaphore
// if state is zero, then block task
if (s->state == 0)
{
// block task
// ?? move task from ready queue to blocked queue
//reschedule the tasks
return 1;
}
// state is non-zero (semaphore already signaled)
s->state = 0; // reset state, and don't block
return 0;
}
else
{
// counting semaphore
s->state--;
// ?? implement counting semaphore
if (s->state < 0)
{
}
}
This is what I have for a try lock so far:
if (s->type == 0)
{
// binary semaphore
// if state is zero, then block task
if (s->state == 0)
{
tcb[curTask].event = s; // block task
tcb[curTask].state = S_BLOCKED;
removeNode(tcb[curTask].priority, READY_QUEUE, curTask);
enqueue(tcb[curTask].priority, curTask, BLOCKED_QUEUE);
return 1;
}
// state is non-zero (semaphore already signaled)
s->state = 1; // reset state, and don't block
return 0;
}
else
{
s->state--;
if (s->state >= 0)
{
s->state++;
}
else
{
tcb[curTask].event = s;
tcb[curTask].state = S_BLOCKED;
removeNode(tcb[curTask].priority, READY_QUEUE, curTask);
enqueue(tcb[curTask].priority, curTask, BLOCKED_QUEUE);
}
}
A regular spin lock is implemented something like this (pseudo-C-codish):
void lock(locktype_t* LockVariable)
{
while (CompareAndSwap(LockVariable,
STATE_UNLOCKED /* state to wait for */,
STATE_LOCKED /* new state to try to set */) !=
STATE_UNLOCKED /* expected state at the beginning of CAS() */)
{
// spin here, doing nothing useful, waiting for *LockVariable to
// first become STATE_UNLOCKED (CAS() returns its last value), after
// which we will set it to STATE_LOCKED (CAS() will do that atomically)
}
}
void unlock(locktype_t* LockVariable)
{
*LockVariable = STATE_UNLOCKED;
}
In case where indefinite spinning and waiting for the lock to become first unlocked is undesirable, we use a loop-less variant of the above something like this:
int tryToLock(locktype_t* LockVariable)
{
if (CompareAndSwap(LockVariable,
STATE_UNLOCKED /* state to wait for */,
STATE_LOCKED /* new state to try to set */) !=
STATE_UNLOCKED /* expected state at the beginning of CAS() */)
{
return 0; // the lock is still held by someone else, bail out
}
return 1; // the lock is now held by us, hurray!
}
Compare-and-swap
I was looking for a non-spin lock trylock.
I have figured out what to do. If it is a counting semaphore, then I decrement if the count is positive and I consume the resource. If it is zero or less, I do nothing but return an error code. I do not decrement the count or consume the resource. The program is then able to continue past that point. If it is a binary semaphore, I consume it if the resource is available. I then change the value of the binary semaphore to consumed. If it isn't available, then I return an error code.

Resources