Thread: Adding items to a bounded buffer in C

  1. #1
    Registered User
    Join Date
    Feb 2017
    Posts
    12

    Adding items to a bounded buffer in C

    So I'm trying to write a program that adds items to a bounded buffer:
    Code:
        #include <pthread.h>
        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
        #include "bbuffer.h"
        
        
        int count;
        pthread_mutex_t mutex;
        pthread_cond_t cond;
        pthread_cond_t cv;
        int bounded_buffer[BOUNDED_BUFFER_SIZE];
        int    pthread_cond_signal(pthread_cond_t *cv);
        int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
        
        
        void initialize_bounded_buffer() {
            int status;
            count = 0;
            status = pthread_mutex_init(&mutex, NULL);
            if (status != 0) {
                fprintf(stderr, "Error creating buffer_mutex\n");
            }
        }
        
        
        void add_to_buffer(int value) {
            printf("adding\n"); 
            pthread_mutex_lock(&mutex);
            while (count == BOUNDED_BUFFER_SIZE){
                printf("waiting");
                pthread_cond_wait(&cond, &mutex);
            }
                printf("no error\n"); 
                bounded_buffer[count] = value;
                count++;
                pthread_cond_signal(&cv);
                printf("added\n");
                printf("%d\n", count);
                pthread_mutex_unlock(&mutex);
        }
    A problem I've been having with this is that I'm running this on a server and when I try to run the add method from this server, the value isn't the correct one and I don't know why. Here's the method which calls the bounded buffer methods:
    Code:
        void *server_action(void *arg) {
            int comm_fd = *(int *)arg;
            char str[OUTPUT_BUFFER_SIZE];
            char operand[OUTPUT_BUFFER_SIZE];
            char result_message[OUTPUT_BUFFER_SIZE];
            char temp_result[OUTPUT_BUFFER_SIZE];
            char *separator = "";
            int  value;
            int  i, sum;
            pc_op_t operation;
        
            bzero(str, OUTPUT_BUFFER_SIZE);
            read(comm_fd, str, OUTPUT_BUFFER_SIZE);
            operation = parse_request(str, operand);
            sprintf(result_message, "%s\n", "GET OFF MY LAWN!");
            switch(operation) {
                case ADD: 
                    printf("server: ADD\n"); 
                    printf("server: parameter is %s\n", operand);
                    /* TO DO something here for ADD */
                    printf("the value is %d\n", value);
                    add_to_buffer(value);
                    break;
                case DEBUG: 
                    printf("server: DEBUG\n"); 
                    return;
                    break;
                case UNKNOWN:
                default:
                    printf("server: UNKNOWN\n"); 
                    break;
            }
        
            send_http_response(comm_fd, result_message);
            close(comm_fd);
            return_thread_index(comm_fd);
        }
    int main() {
    
        /* Vars for setting up heartbeat */
        pthread_t heart;
        int interval = 5;
    
        /* Vars for setting up server threads */
        char str[OUTPUT_BUFFER_SIZE];
        int listen_fd, comm_fd;
        int i;
        int thread_index;
        int num_threads = 0;
        int bind_result;
        void *result;
        int status;
        
    
        initialize();
        
    
        /*
         * First start the heartbeat -- just to convince ourselves that
         * "accept()" is not blocking the whole process... 
         *
         */
    
        if (pthread_create(&heart, 0, heartbeat, (void *)&interval) < 0) {
            fprintf(stderr, "Could not create heartbeat thread\n");
            return 1; 
        }
    
    
        /*
         * Now set up server threads as needed -- i.e., as separate clients
         * connect to the server.
         */
    
        listen_fd = setup_listener();
    
        while (comm_fd = accept(listen_fd, (struct sockaddr*) NULL, NULL)) {
    
            thread_index = grab_thread_index();
            if (thread_index == -1) {
                fprintf(stderr, "No more threads available.\n");
                exit(1);
            }
    
            set_thread_fd(thread_index, comm_fd);
    
            if (pthread_create(&thread_pool[thread_index], 0, 
                    server_action, &comm_fd) < 0)
            {
                fprintf(stderr, "Could not create thread %d\n", num_threads);
                exit(1);
            }
    
            printf("Created server thread %d\n", num_threads);
        }
    }
    Now if I run the curl command on this server then no matter what I put in as the value (for example curl "localhost (port number)/?op=add&val=167") then the value is always 0 for some reason and I'm not sure what int I have to pass into my add method so that the correct value is added.

  2. #2
    Registered User
    Join Date
    Feb 2017
    Posts
    12
    Ok so I found out that operand is not an integer but the address to an integer. So I guess my question is how do I pass in the actual integer instead of the address?

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,666
    > if (pthread_create(&thread_pool[thread_index], 0,
    > server_action, &comm_fd) < 0)
    You're passing a pointer to a variable which may change it's value before server_action gets a chance to run and inspect the value.

    Try
    Code:
            if (pthread_create(&thread_pool[thread_index], 0, 
                    server_action, (void*)comm_fd) < 0)
    with
    Code:
    void *server_action(void *arg) {
            int comm_fd = (int)arg;

    > bzero(str, OUTPUT_BUFFER_SIZE);
    > read(comm_fd, str, OUTPUT_BUFFER_SIZE);
    There are several things wrong here.
    1. You don't pay any attention to the return result of read.
    2. If read does actually fill the buffer, you won't have a \0 terminated string that your bzero attempts to solve.

    Thread programming is a minefield.
    Network programming is another minefield - Fallacies of distributed computing - Wikipedia

    Also, there is NO guarantee that if the client sends "hello world" that the server will read "hello world" in a single call to read().
    Sure it's fairly guaranteed when you're just on localhost, but if it's a stressed server on the other side of the planet, you might get "he" "l" "l" "o wo" "rld" dribbled to you a few bytes at a time.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 7
    Last Post: 02-05-2017, 09:16 PM
  2. ListView controls - Adding items .. What the beep?
    By IceDane in forum Windows Programming
    Replies: 7
    Last Post: 04-08-2008, 12:07 PM
  3. Segmentation fault when executing bounded buffer program
    By Megalodon01 in forum C Programming
    Replies: 7
    Last Post: 03-31-2008, 12:19 AM
  4. Adding items to the beginning of a file
    By Dunners in forum C++ Programming
    Replies: 1
    Last Post: 02-20-2005, 09:13 AM
  5. Adding Items to Combo Boxes
    By tenthirty in forum Windows Programming
    Replies: 10
    Last Post: 12-21-2001, 02:37 AM

Tags for this Thread