compilation problem - variable was not declared in this scope
Can anyone look at this code and let me know why pthread_mutex_unlock
and pthread_mutex_lock are giving me the "phtread_mutex_unlock" was
not defined in this scope error.
I am compiling the code on g++.
[root@localhost Stargate_GPS]# g++ -v
Using built-in specs.
Target: i386-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --
infodir=/usr/share/info --enable-shared --enable-threads=posix --
enable-checking=release --with-system-zlib --enable-__cxa_atexit --
disable-libunwind-exceptions --enable-libgcj-multifile --enable-
languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --
disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-
gcj-1.4.2.0/jre --with-cpu=generic --host=i386-redhat-linux
Thread model: posix
gcc version 4.1.1 20070105 (Red Hat 4.1.1-51)
The header file is:
----------------
#ifndef UDP_COMM_H
#define UDP_COMM_H
// General Requirements
#include <iostream>
// UDP requirements
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
// Serial requirements
#include <stdio.h> // Standard input/output definitions
#include <string> // String function definitions
#include <unistd.h> // UNIX standard function definitions
#include <fcntl.h> // File control definitions
#include <termios.h> // POSIX terminal control definitions
#define MAXCOMMBUF 1024
#define MAXWAIT 100
#define GPS_PORT "/dev/tts/0"
#define ROBO_PORT "/dev/tts/2"
#define ROBO_COMM_SIZE 13
// Communications data structure definition
struct commdata {
char* address;
char* port;
pthread_mutex_t inlock, outlock, contlock; // mutex
int receive;
int send;
int stop;
int insize, outsize;
char inbuff[MAXCOMMBUF];
char outbuff[MAXCOMMBUF];
int fd; //file descriptor
};
using namespace std;
void* commThread(void* arg); // wrapper function for thread function
call
int open_port(commdata* data, int speed);
int open_socket(commdata* data, struct sockaddr_in &read_addr,struct
sockaddr_in &write_addr);
#endif
----------------
The source is:
-------------------
#include "comm.h"
void* commThread(void* arg)
{
// Comm control variables
int count = 0;
int nb, nbytes, outsize;
fd_set read_template;
struct timeval wait;
// Comm thread buffers
char readbuff[MAXCOMMBUF];
char writebuff[MAXCOMMBUF];
for (int i=0;i<MAXCOMMBUF;i++) {
readbuff[i] = 0;
writebuff[i] = 0;
}
// Thread input pointer
commdata** data = (commdata**) arg;
////////////////////////////////////
// UDP socket setup
////////////////////////////////////
int sockfd;
struct sockaddr_in read_addr, write_addr;
sockfd = open_socket(data[0], read_addr, write_addr);
if (sockfd < 0) return(NULL);
cout << "UDP socket now opened" << endl;
////////////////////////////////////
// serial port setup
////////////////////////////////////
int curport[2];
// opening port with fixed options
curport[0] = open_port(data[1], B19200);
if (curport[0] < 0) return(NULL);
curport[1] = open_port(data[2], B115200);
if (curport[1] < 0) return(NULL);
cout << "Serial ports now opened" << endl;
////////////////////////////////////
// Main Loop
////////////////////////////////////
while(1) {
// Check if thread should quit
pthread_mutex_lock(&(data[2]->contlock));
if (data[2]->stop) {
cout << "Serial thread received exit command" << endl;
pthread_mutex_unlock(&(data[2]->contlock));
break;
}
pthread_mutex_unlock(&(data[2]->contlock));
// Check for available packets with timeout
// set timeout
wait.tv_sec = 0;
wait.tv_usec = MAXWAIT;
// define where to read from
FD_ZERO(&read_template);
FD_SET(sockfd, &read_template);
FD_SET(curport[0], &read_template);
FD_SET(curport[1], &read_template);
// Check udp and both serial ports to see if data is available
if ((nb = select(FD_SETSIZE, &read_template, NULL,NULL, &wait)) >
0) {
//cout << "Data available:" << FD_ISSET(curport[0],
&read_template) << " " << FD_ISSET(curport[1], &read_template) << " "
<< FD_ISSET(sockfd, &read_template) << endl;
// Read serial data if available
for (int i=0;i<2;i++) {
if (FD_ISSET(curport[i], &read_template)) {
nbytes = read(curport[i], readbuff, MAXCOMMBUF);
//cout << "Serial " << i+1 << ": " << nbytes << endl;
if (nbytes < 0) {
cout << " Read error" << endl;
continue;
} else if (nbytes > 0) {
pthread_mutex_lock(&(data[i+1]->inlock));
for (int j=0;j<nbytes;j++) {
// Check inbuff overflow
if (data[i+1]->insize+j >= MAXCOMMBUF) {
data[i+1]->insize = 0;
cout << "Serial thread inbuff overflow" << endl;
}
// Copy readbuff to inbuff
data[i+1]->inbuff[data[i+1]->insize+j] = readbuff[j];
readbuff[j] = 0;
}
data[i+1]->insize += nbytes;
data[i+1]->receive = 1;
pthread_mutex_unlock(&(data[i+1]->inlock));
}
}
}
// Read UDP data if available
if (FD_ISSET(sockfd, &read_template)) {
nbytes = read(sockfd, readbuff, MAXCOMMBUF);
if (nbytes < 0) {
cout << " Read error" << endl;
continue;
}
// save received data
pthread_mutex_lock(&(data[0]->inlock));
for (int i=0;i<nbytes;i++) {
if (data[0]->insize+i >= MAXCOMMBUF) {
data[0]->insize = 0;
cout << "UDP thread inbuff overflow" << endl;
}
data[0]->inbuff[data[0]->insize + i] = readbuff[i];
}
count++;
data[0]->insize += nbytes;
data[0]->receive = 1;
pthread_mutex_unlock(&(data[0]->inlock));
}
}
// Check if udp packet is ready to send
pthread_mutex_lock(&(data[0]->outlock));
if (!(data[0]->send)) {
pthread_mutex_unlock(&(data[0]->outlock));
} else {
// grab data to transmit
for (int i=0;i<data[0]->outsize;i++) {
writebuff[i] = data[0]->outbuff[i];
}
// reset transmit flag
outsize = data[0]->outsize;
data[0]->outsize = 0;
data[0]->send = 0;
pthread_mutex_unlock(&(data[0]->outlock));
// send individual udp packets
if (sendto(sockfd,writebuff,sizeof(char)*outsize,0,(struct sockaddr
*)&write_addr,sizeof(write_addr)) < 0) {
cout << "Error Transmitting data packet to ground" << endl;
}
// send udp packet to screen
// cout << "UDP Out Packet: " ;
// for (int j=0;j<outsize;j++) {
// cout << (int) writebuff[j] << " ";
// }
// cout << endl;
// cout << "UDP Output size: " << outsize << endl;
}
// Check if serial packet is ready to send
for (int i=0;i<2;i++) {
pthread_mutex_lock(&(data[i+1]->outlock));
if (!(data[i+1]->send)) {
pthread_mutex_unlock(&(data[i+1]->outlock));
} else {
// grab data to transmit
for (int j=0;j<data[i+1]->outsize;j++) {
writebuff[j] = data[i+1]->outbuff[j];
}
outsize = data[i+1]->outsize;
// reset transmit flag
data[i+1]->outsize = 0;
data[i+1]->send = 0;
pthread_mutex_unlock(&(data[i+1]->outlock));
// send serial packet
nb = write(curport[i], writebuff, outsize*sizeof(char));
// if (i == 1) {
// cout << "Serial out: " ;
// for (int j=0;j<outsize;j++) {
// cout << (int) writebuff[j] << " ";
// if (j>0) {
// if ((writebuff[j-1] ==16) && (writebuff[j]==3)) cout <<
endl;
// }
// }
// cout << endl;
// }
}
}
}
// Close comm items
close(sockfd);
cout << "UDP socket closed, thread terminated" << endl;
for (int i=0;i<2;i++) {
close(curport[i]);
}
cout << "Serial ports closed, thread terminated" << endl;
return(NULL);
}
// 'open_port()' - Open serial port.
// Returns the file descriptor on success or -1 on error.
int open_port(commdata* data, int speed)
{
int fd; // File descriptor for the port
struct termios options;
fd = open(data->port, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1) {
//Could not open the port.
perror("open_port: Unable to open serial port - ");
}
else {
// Read currently available data without blocking;
//fcntl(fd, F_SETFL, FNDELAY);
// Read currently available data with blocking;
fcntl(fd, F_SETFL, 0);
}
// Get default attributes
tcgetattr(fd, &options);
// Clear all default attributes
bzero(&options,sizeof(options));
// Enable the receiver and set local mode...
options.c_cflag = CS8 | CLOCAL | CREAD;
// Ensure no dumb options are on. Ignore breaks or bytes with parity
errors
options.c_iflag = IGNBRK|IGNPAR;
options.c_oflag = 0;
options.c_lflag = 0; //~(ICANON | ECHO | ECHOE | ISIG); // Set the
new options for the port...
// Set the baud rates to speed
cfsetispeed(&options, speed);
cfsetospeed(&options, speed);
/*// Set to 8N1
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
// Disable flow control
options.c_cflag &= ~CRTSCTS;
options.c_iflag &= ~ICRNL;
options.c_iflag &= ~(IXON | IXOFF | IXANY);
// Enable the receiver and set local mode...
options.c_cflag |= (CLOCAL | CREAD);
// The magical line, turn the port to non-canonical mode so it just
spits data out.
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
// Setup output options
options.c_oflag = 0;
*/
// Set the new options for the port...
tcsetattr(fd, TCSANOW, &options);
return (fd);
}
int open_socket(commdata* data, struct sockaddr_in &read_addr,struct
sockaddr_in &write_addr)
{
int sockfd;
struct hostent *hp;
// Open a UDP socket (an Internet datagram socket).
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
cout << "Unable to open UDP socket" << endl;
return (sockfd);
}
// Setup local address
bzero((char *) &read_addr, sizeof(read_addr));
read_addr.sin_family = AF_INET;
read_addr.sin_addr.s_addr = INADDR_ANY;
read_addr.sin_port = htons(atoi(data->port));
if (bind (sockfd, (struct sockaddr *)&read_addr, sizeof(read_addr))
< 0) {
cout << "Error binding to port " << data->port << endl;
return (sockfd);
}
// Setup remote address
if ((hp = gethostbyname(data->address)) == 0){
cout << "Unable to get host by name" << endl;
return (sockfd);
}
bzero((char *) &write_addr, sizeof(write_addr));
write_addr.sin_family = AF_INET;
bcopy((char *)hp->h_addr, (char *)&write_addr.sin_addr, hp-
h_length);
write_addr.sin_port = htons(atoi(data->port));
return (sockfd);
}
-------------------
The following are the errors:
comm.c: In function 'void* commThread(void*)':
comm.c:50: error: 'pthread_mutex_lock' was not declared in this scope
comm.c:53: error: '::pthread_mutex_unlock' has not been declared
comm.c:56: error: 'pthread_mutex_unlock' was not declared in this
scope
Thanks