Assertion failed: (lt_write != NULL || lt_read != NULL), function lthread_run, file lthread_sched.c, line 252.
Opened this issue · 2 comments
To run an lthread scheduler in each pthread, launch a pthread and create lthreads using lthread_create() followed by lthread_run() in each pthread.
when create more then one pthread and lthread scheduler,and use "ab -c 100 -n 10000" to test program,then "Assertion failed: (lt_write != NULL || lt_read != NULL), function lthread_run, file lthread_sched.c, line 252." occure.
But only one pthread will run ok.
static
void* accept_loop(void* args)
{
lthread_t *lt = NULL;
lthread_create(<, listener, NULL);
lthread_run();
}
int
main(int argc, char **argv)
{
......
int num = 4;
int i = 0;
pthread_t ths[num];
while (i++ < num) {
pthread_create(&ths[i], NULL, accept_loop, NULL);
}
i = 0;
while (i++ < num) {
pthread_join(ths[i], NULL);
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <lthread.h>
struct cli_info {
/* other stuff if needed*/
struct sockaddr_in peer_addr;
int fd;
};
typedef struct cli_info cli_info_t;
char *reply = "HTTP/1.0 200 OK\r\nContent-length: 11\r\n\r\nHello Kannan";
int lsn_fd = 0;
void
http_serv(void *arg)
{
cli_info_t *cli_info = arg;
char *buf = NULL;
unsigned long long int ret = 0;
char ipstr[INET6_ADDRSTRLEN];
lthread_detach();
inet_ntop(AF_INET, &cli_info->peer_addr.sin_addr, ipstr, INET_ADDRSTRLEN);
printf("Accepted connection on IP %s\n", ipstr);
if ((buf = malloc(1024)) == NULL)
return;
/* read data from client or timeout in 5 secs */
ret = lthread_recv(cli_info->fd, buf, 1024, 0, 5000);
/* did we timeout before the user has sent us anything? */
if (ret == -2) {
lthread_close(cli_info->fd);
free(buf);
free(arg);
return;
}
/* reply back to user */
lthread_send(cli_info->fd, reply, strlen(reply), 0);
lthread_close(cli_info->fd);
free(buf);
free(arg);
}
void
listener(lthread_t *lt, void *arg)
{
int cli_fd = 0;
int ret = 0;
struct sockaddr_in peer_addr = {};
socklen_t addrlen = sizeof(peer_addr);
lthread_t *cli_lt = NULL;
cli_info_t *cli_info = NULL;
char ipstr[INET6_ADDRSTRLEN];
DEFINE_LTHREAD;
while (1) {
/* block until a new connection arrives */
cli_fd = lthread_accept(lsn_fd, (struct sockaddr*)&peer_addr, &addrlen);
if (cli_fd == -1) {
perror("Failed to accept connection");
return;
}
if ((cli_info = malloc(sizeof(cli_info_t))) == NULL) {
close(cli_fd);
continue;
}
cli_info->peer_addr = peer_addr;
cli_info->fd = cli_fd;
/* launch a new lthread that takes care of this client */
ret = lthread_create(&cli_lt, http_serv, cli_info);
}
}
static
void* accept_loop(void* args)
{
lthread_t *lt = NULL;
lthread_create(<, listener, NULL);
lthread_run();
}
int
main(int argc, char **argv)
{
int cli_fd = 0;
int opt = 1;
int ret = 0;
struct sockaddr_in sin = {};
lthread_t *cli_lt = NULL;
cli_info_t *cli_info = NULL;
char ipstr[INET6_ADDRSTRLEN];
lthread_t *lt = NULL;
/* create listening socket */
lsn_fd = lthread_socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (lsn_fd == -1)
return 0;
if (setsockopt(lsn_fd, SOL_SOCKET, SO_REUSEADDR, &opt,sizeof(int)) == -1)
perror("failed to set SOREUSEADDR on socket");
sin.sin_family = PF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(3128);
/* bind to the listening port */
ret = bind(lsn_fd, (struct sockaddr *)&sin, sizeof(sin));
if (ret == -1) {
perror("Failed to bind on port 3128");
return 0;
}
printf("Starting listener on 3128\n");
listen(lsn_fd, 128);
int num = 4;
int i = 0;
pthread_t ths[num];
while (i++ < num) {
pthread_create(&ths[i], NULL, accept_loop, NULL);
}
i = 0;
while (i++ < num) {
pthread_join(ths[i], NULL);
}
return 0;
}