Assertion failed: (lt_write != NULL || lt_read != NULL), function lthread_run, file lthread_sched.c, line 252.
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;
}