A useful helper function for opening a socket connection to a server was introduced in the course: int open_clientfd(char *hostname, int port) { int clientfd; struct hostent *hp; struct sockaddr_in serveraddr; if ((clientfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) return -1; /* check errno for cause of error */ // !!!!!!!!!! NOT THREAD SAFE !!!!!!!!!! /* Fill in the server's IP address and port */ if ((hp = gethostbyname(hostname)) == NULL) return -2; /* check h_errno for cause of error */ // !!!!!!!!!! NOT THREAD SAFE !!!!!!!!!! bzero((char *) &serveraddr, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; bcopy((char *)hp->h_addr_list[0], (char *)&serveraddr.sin_addr.s_addr, hp->h_length); serveraddr.sin_port = htons(port); /* Establish a connection with the server */ if (connect(clientfd, (SA *) &serveraddr, sizeof(serveraddr)) < 0) return -1; return clientfd; } The problem with this function is that it is not thread safe: it uses function gethostbyname, which returns a pointer to a static variable. On the following page, reimplement open_clientfd in a thread safe way using the lock-and-copy technique. (Note 1: that the new function will take an additional input: a semaphore that will control access to the critical section so only one thread at a time can call gethostbyname and read the result stored in a static variable. Note 2: a call to malloc is not necessary as the hostentry local variable lives on the current thread's stack.) int open_clientfd_ts(char *hostname, int port, sem_t *mutexp) { int clientfd; struct hostent hostentry, *hp = &hostentry; struct hostent *temp_hp; struct sockaddr_in serveraddr; if ((clientfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) return -1; /* check errno for cause of error */ /* Use lock-and-copy to keep this function thread safe */ // Implement solution here !!! /* Fill in the server's IP address and port */ bzero((char *) &serveraddr, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; bcopy((char *)hp->h_addr, (char *)&serveraddr.sin_addr.s_addr, hp->h_length); serveraddr.sin_port = htons(port); /* Establish a connection with the server */ if (connect(clientfd, (SA *) &serveraddr, sizeof(serveraddr)) < 0) return -1; return clientfd;

icon
Related questions
Question
A useful helper function for opening a socket connection to a server was introduced in the course:
int open_clientfd(char *hostname, int port)
{
int clientfd;
struct hostent *hp;
struct sockaddr_in serveraddr;
if ((clientfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
return -1; /* check errno for cause of error */
// !!!!!!!!!! NOT THREAD SAFE !!!!!!!!!!
/* Fill in the server's IP address and port */
if ((hp = gethostbyname(hostname)) == NULL)
return -2; /* check h_errno for cause of error */
// !!!!!!!!!! NOT THREAD SAFE !!!!!!!!!!
bzero((char *) &serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
bcopy((char *)hp->h_addr_list[0],
(char *)&serveraddr.sin_addr.s_addr, hp->h_length);
serveraddr.sin_port = htons(port);
/* Establish a connection with the server */
if (connect(clientfd, (SA *) &serveraddr, sizeof(serveraddr)) < 0)
return -1;
return clientfd;
}
The problem with this function is that it is not thread safe: it uses function gethostbyname, which
returns a pointer to a static variable. On the following page, reimplement open_clientfd in a thread
safe way using the lock-and-copy technique. (Note 1: that the new function will take an additional
input: a semaphore that will control access to the critical section so only one thread at a time can call
gethostbyname and read the result stored in a static variable. Note 2: a call to malloc is not necessary
as the hostentry local variable lives on the current thread's stack.)
Transcribed Image Text:A useful helper function for opening a socket connection to a server was introduced in the course: int open_clientfd(char *hostname, int port) { int clientfd; struct hostent *hp; struct sockaddr_in serveraddr; if ((clientfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) return -1; /* check errno for cause of error */ // !!!!!!!!!! NOT THREAD SAFE !!!!!!!!!! /* Fill in the server's IP address and port */ if ((hp = gethostbyname(hostname)) == NULL) return -2; /* check h_errno for cause of error */ // !!!!!!!!!! NOT THREAD SAFE !!!!!!!!!! bzero((char *) &serveraddr, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; bcopy((char *)hp->h_addr_list[0], (char *)&serveraddr.sin_addr.s_addr, hp->h_length); serveraddr.sin_port = htons(port); /* Establish a connection with the server */ if (connect(clientfd, (SA *) &serveraddr, sizeof(serveraddr)) < 0) return -1; return clientfd; } The problem with this function is that it is not thread safe: it uses function gethostbyname, which returns a pointer to a static variable. On the following page, reimplement open_clientfd in a thread safe way using the lock-and-copy technique. (Note 1: that the new function will take an additional input: a semaphore that will control access to the critical section so only one thread at a time can call gethostbyname and read the result stored in a static variable. Note 2: a call to malloc is not necessary as the hostentry local variable lives on the current thread's stack.)
int open_clientfd_ts(char *hostname, int port, sem_t *mutexp)
{
int clientfd;
struct hostent hostentry, *hp = &hostentry;
struct hostent *temp_hp;
struct sockaddr_in serveraddr;
if ((clientfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
return -1; /* check errno for cause of error */
/* Use lock-and-copy to keep this function thread safe */
// Implement solution here !!!
/* Fill in the server's IP address and port */
bzero((char *) &serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
bcopy((char *)hp->h_addr,
(char *)&serveraddr.sin_addr.s_addr, hp->h_length);
serveraddr.sin_port = htons(port);
/* Establish a connection with the server */
if (connect(clientfd, (SA *) &serveraddr, sizeof(serveraddr)) < 0)
return -1;
return clientfd;
Transcribed Image Text:int open_clientfd_ts(char *hostname, int port, sem_t *mutexp) { int clientfd; struct hostent hostentry, *hp = &hostentry; struct hostent *temp_hp; struct sockaddr_in serveraddr; if ((clientfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) return -1; /* check errno for cause of error */ /* Use lock-and-copy to keep this function thread safe */ // Implement solution here !!! /* Fill in the server's IP address and port */ bzero((char *) &serveraddr, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; bcopy((char *)hp->h_addr, (char *)&serveraddr.sin_addr.s_addr, hp->h_length); serveraddr.sin_port = htons(port); /* Establish a connection with the server */ if (connect(clientfd, (SA *) &serveraddr, sizeof(serveraddr)) < 0) return -1; return clientfd;
Expert Solution
steps

Step by step

Solved in 2 steps

Blurred answer