multithreading - Changing address contained by structure and its members using function (ANSI C) -


[edit]i added main code , of external functions used code. code quite long, in summary sends message device measuring parameters of water in container, , device responds corresponding value measured sensor. after code uses value modify level , temperature of water. prints current status of container , makes log.txt file.[/edit]

i want constructor object-oriented-like function in c, address of structure , members not being changed after malloc() them. saw answer changing address contained pointer using function , got idea of problem is, still can't solve it. below code doing constructor:

udp.c

#include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include "udp.h" #define buf_size 1000 #define header_size  typedef struct{     int socket;     char header[4];     float *send_value;     char *message_buffer; }message;   void build_message(message **msg, int socket, char header[], float *send_value){     *msg = (message *)malloc(sizeof(message));     (*msg)->socket = socket;     strncpy((*msg)->header, header, 4);     (*msg)->send_value = send_value;      (*msg)->message_buffer = null;      (*msg)->message_buffer = malloc(buf_size);     //(**msg).message_buffer = (char *)(msg+sizeof(int) + sizeof(float *) + sizeof(char *)*3); }  int prepara_socket_cliente(char *host, char *porta) {      struct addrinfo hints;     struct addrinfo *result, *rp;     int sfd, s;      /* obtain address(es) matching host/port */      memset(&hints, 0, sizeof(struct addrinfo));     hints.ai_family = af_unspec;    /* allow ipv4/ or ipv6 */     hints.ai_socktype = sock_dgram; /* datagram socket */     hints.ai_flags = 0;     hints.ai_protocol = 0;          /* protocol */      s = getaddrinfo(host, porta, &hints, &result);     if (s != 0) {         fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));         exit(exit_failure);     }      /* getaddrinfo() returns list of address structures.        try each address until connect(2).        if socket(2) (or connect(2)) fails, (close socket        and) try next address. */      for( rp = result; rp != null; rp = rp->ai_next) {         sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);         if (sfd == -1)             continue;          if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1)             break;                  /* success */          close(sfd);     }      if (rp == null) {               /* no address succeeded */         fprintf(stderr, "could not connect\n");         exit(exit_failure);     }      freeaddrinfo(result);           /* no longer needed */      return sfd; }  float receive_message(message *msg){     ssize_t nread;     int len;     //sprintf(msg->message_buffer, "%s0.0", msg->header);     len = strlen(msg->message_buffer)+1;     int rc;     if (len + 1 > buf_size){         fprintf(stderr, "ignoring long message in argument\n");         exit(exit_failure);     }     if((rc = write(msg->socket, msg->message_buffer, len)) != len){         printf("%d, %d\n", len, rc);         fprintf(stderr, "partial/failed write\n");         exit(exit_failure);     }      nread = read(msg->socket, msg->message_buffer, buf_size);     if (nread == -1){         perror("read");         exit(exit_failure);     }     return atof(msg->message_buffer+3); }  int send_message(message *msg){     ssize_t nread;     int len;     //sprintf(msg->message_buffer, "%s%.1f", msg->header, *msg->send_value);     len = strlen(msg->message_buffer)+1;     int rc;     if (len + 1 > buf_size){         fprintf(stderr, "ignoring long message in argument\n");         exit(exit_failure);     }     if((rc = write(msg->socket, msg->message_buffer, len)) != len){         printf("%d, %d\n", len, rc);         fprintf(stderr, "partial/failed write\n");         exit(exit_failure);     }      nread = read(msg->socket, msg->message_buffer, buf_size);     if (nread == -1){         perror("read");         exit(exit_failure);     }     return 0; } 

main.c

#include<pthread.h> #include<stdio.h> #include<errno.h>  #include<stdlib.h> #include<string.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<arpa/inet.h> #include<netdb.h> #include<unistd.h> #include<math.h> #include<time.h> #include<termios.h> #include"controller.h" #include"screen.h" #include"myio.h" #include"my_time.h" #include"data_structures.h" #include"udp.h"  #define num_threads 5 #define max_param_size  20 #define max_buffer_size 1200 //variables  typedef enum {idle, quit, change_level_ref, change_temp_ref} command_type; struct timespec t1; struct timespec t2; pthread_cond_t screen = pthread_cond_initializer; pthread_cond_t cmd = pthread_cond_initializer; pthread_cond_t barrier = pthread_cond_initializer; int count[2] = {0,0}; command_type command = idle; double_buffer* log_buffer; char* port = null; char* host = null;; int socket_cliente; real ta, ti, no; real t=0; real h=0; real q=0; real nf=0; real ni=0; real na=0; real href = 2.0; real tref = 25.0; pthread_mutex_t em_scan; pthread_mutex_t em;  void init(){     port = (char *)malloc(sizeof(char)*max_param_size);     host = (char *)malloc(sizeof(char)*max_param_size);     log_buffer = build_double_buffer(); } //threads  void *levelcontrol(void *threadid){ /**********************************************************  *thread responsible controling water level  *********************************************************/     controller* levelcontrol = null;     levelcontrol = build_controller();     levelcontrol->kp = 10000.0;     levelcontrol->ki = 0.0;     levelcontrol->kd = 0.0;     levelcontrol->error_thresh =  1.0;     levelcontrol->step_time = 0.7;     levelcontrol->max_actuator_value = 100.0;     levelcontrol->min_actuator_value = 0.0;     int intervalo = 90000000;     message *message_h = null;     build_message(&message_h, socket_cliente, "sh-", &h);     sprintf(message_h->message_buffer, "%s0.0", message_h->header);     message *message_nf = null;     build_message(&message_nf, socket_cliente, "anf", &nf);     message *message_ni = null;     build_message(&message_ni, socket_cliente, "ani", &ni); loop_1:     if(command != quit){         pthread_mutex_lock(&em);         h = receive_message(message_h);         levelcontrol->error = href - h;          if(levelcontrol->error < 0.0){             levelcontrol->error = -levelcontrol->error;             nf = pid_update(levelcontrol);             ni = 0.0;         }else{             ni = pid_update(levelcontrol);             nf = 0.0;         }         sprintf(message_nf->message_buffer, "%s%f", message_nf->header, *message_nf->send_value);         send_message(message_nf);         sprintf(message_ni->message_buffer, "%s%f", message_ni->header, *message_ni->send_value);         send_message(message_ni);         count[1] = 1;         if((count[0] == 1) & (count[1] == 1))   pthread_cond_signal(&barrier);         next_timer(t1, intervalo);         pthread_mutex_unlock(&em);         goto loop_1;     }else return null; }  void *tempcontrol(void *threadid){ /**********************************************************  * thread responsible controling temperature  *********************************************************/      controller *tempcontrol = null;     tempcontrol = build_controller();     tempcontrol->kp = 10000.0;     tempcontrol->ki = 0.0;     tempcontrol->kd = 0.0;     tempcontrol->error_thresh =  20.0;     tempcontrol->step_time = 0.7;     tempcontrol->max_actuator_value = 10000.0;     tempcontrol->min_actuator_value = 0.0;     int intervalo = 70000000;      message *message_t = null;     build_message(&message_t, socket_cliente, "st-", &t);     sprintf(message_t->message_buffer, "%s0.0", message_t->header);     message *message_q = null;     build_message(&message_q, socket_cliente, "aq-", &q);     message *message_na = null;     build_message(&message_na, socket_cliente, "ana", &na);     char *log_string = null;         log_string = (char *)malloc(sizeof(char)*max_buffer_size); //  while(command != quit){ loop_2:     if(command != quit){         pthread_mutex_lock(&em);         t = receive_message(message_t);         tempcontrol->error = tref - t;           q = pid_update(tempcontrol);         sprintf(message_q->message_buffer, "%s%f", message_q->header, *message_q->send_value);         send_message(message_q);         if(q == tempcontrol->max_actuator_value){             na = 10.0;         }else if(q == tempcontrol->min_actuator_value){             na = 0.0;         }         sprintf(message_na->message_buffer, "%s%f", message_na->header, *message_na->send_value);         send_message(message_na);         count[0] = 1;         if((count[0] == 1) & (count[1] == 1))   pthread_cond_signal(&barrier);         pthread_mutex_unlock(&em);         sprintf(log_string, "temperura: %f\n", t);         setdoublebuffer(log_buffer, log_string);         next_timer(t2, intervalo);         goto loop_2;     }else return null; //  pthread_exit(null); }  void *status(void *threadid){ /**********************************************************  *thread responsible printing current status on   *the screen , setting tref , href  *********************************************************/     message *message_ta = null;     build_message(&message_ta, socket_cliente, "sta", &ta);     sprintf(message_ta->message_buffer, "%s0.0", message_ta->header);     message *message_ti = null;     build_message(&message_ti, socket_cliente, "sti", &ti);     sprintf(message_ti->message_buffer, "%s0.0", message_ti->header);     message *message_no = null;     build_message(&message_no, socket_cliente, "sno", &no);     sprintf(message_no->message_buffer, "%s0.0", message_no->header);     pthread_mutex_lock(&em);     while((count[0] != 1) | (count[1] != 1))    pthread_cond_wait(&barrier, &em);     pthread_mutex_unlock(&em);     //while(command != quit){ loop_3:      switch(command){         case idle:             pthread_mutex_lock(&em);             clearscreen();             ta = receive_message(message_ta);             ti = receive_message(message_ti);             no = receive_message(message_no);             printf("/********************************************************************************************************\n");             printf("*status\n");             printf("*reference temperature: %f\n", tref);             printf("*reference water level: %f\n", href);             printf("*current temperature: %f\n", t);             printf("*current water level: %f\n", h);             printf("*other sensor value => ni = %f, no = %f, na = %f, nf = %f, ta = %f, ti = %f\n", ni, no, na, nf, ta,ti);             printf("*\n");             printf("*\n");             printf("*\n");             printf("*(q)uit, change (l)evel reference, change (t)emperature reference\n");             pthread_mutex_unlock(&em);             sleep(1);             break;         case change_level_ref:             pthread_mutex_lock(&em_scan);             printf("insert new level reference\n");             scanf("%f", &href);             pthread_cond_signal(&screen);             while(command != idle){                 pthread_cond_wait(&cmd, &em_scan);             }             pthread_mutex_unlock(&em_scan);             break;         case change_temp_ref:             pthread_mutex_lock(&em_scan);             printf("insert new temperature reference\n");             scanf("%f", &tref);             pthread_cond_signal(&screen);             while(command != idle){                 pthread_cond_wait(&cmd, &em_scan);             }             pthread_mutex_unlock(&em_scan);         case quit:             fprintf(stderr, "get saiu\n");             return null;     }     goto loop_3;         //return null;  }    void *getreferences(void *threadid){ /**********************************************************  *thread responsible changing program mode  *********************************************************/     char temp;     //while(command != quit){ loop_4:     temp = getch();     switch(temp){         case 'q':             command = quit;         printf("%c\n --------------------------------------------------------\n", temp);             return null;         case 'l':             pthread_mutex_lock(&em_scan);             command = change_level_ref;             pthread_cond_wait(&screen, &em_scan);             command = idle;             pthread_cond_signal(&cmd);             pthread_mutex_unlock(&em_scan);              break;         case 't':             pthread_mutex_lock(&em_scan);             command = change_temp_ref;             pthread_cond_wait(&screen, &em_scan);             command = idle;             pthread_cond_signal(&cmd);             pthread_mutex_unlock(&em_scan);         }     goto loop_4; }  void *log(void *threadid){     char *receive_buffer = null;     receive_buffer = (char *)malloc(sizeof(char)*max_buffer_size);     //while(command != quit){ loop_5:     if(command != quit){         get_buffer(receive_buffer, log_buffer);         write_log(receive_buffer);         goto loop_5;     }else return null; }  int main (int argc, char *argv[]){     init();     pthread_mutex_init(&em_scan, null);     pthread_mutex_init(&em, null);     init_nano_timer(t1);     init_nano_timer(t2);     clearscreen();     printf("enter port used in udp communication\n");     scanf("%s", port);     strcpy(host, "localhost");     socket_cliente = prepara_socket_cliente(host, port);     pthread_t threads[num_threads];     int rc;     int t;     void *threadname[num_threads];     threadname[0] = tempcontrol;     threadname[1] = levelcontrol;     threadname[2] = status;     threadname[3] = getreferences;     threadname[4] = log;     for(t=0; t<num_threads; t++){         rc = pthread_create(&threads[t], null, threadname[t], (void *)t);         if(rc){             printf("error; return code pthread_create() %d\n", rc);             exit(1);         }     }      for(t=0; t<num_threads; t++){         rc = pthread_join(threads[t], null);         if(rc){             printf("error; return code pthread_create() %d\n", rc);             exit(1);         }     }     return 0; } 

btw, using threads in these code, code thread-safe without mutexes?

as @sourav ghosh rightly commented you:

void build_message(message **msg, int socket, char header[], float *send_value) {     *msg = malloc(sizeof(message));     (*msg)->socket = socket;     strncpy((*msg)->header, header, 4);     (*msg)->send_value = send_value;      (*msg)->message_buffer = malloc(buf_size); } 

change structure to:

typedef struct{     int socket;     char header[4];     float *send_value;     char *message_buffer; }message; 

Comments

Popular posts from this blog

Java 3D LWJGL collision -

spring - SubProtocolWebSocketHandler - No handlers -

methods - python can't use function in submodule -