473,763 Members | 7,719 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Seg Fault - Can not access memory ?

I am trying to implement a webserver with boss-worker model thread
pool implementation -

I have a header declaration threadpool.h as -

typedef struct threadpool_work {
void (*routine) ();
void *arg;
struct threadpool_work *next;
} threadpool_work _t;

typedef struct threadpool {
/* Pool Characteristics */
int num_threads;
int max_queue_size;

int do_not_block_wh en_full;
pthread_t *threads;
int cur_queue_size;
threadpool_work _t *queue_head;
threadpool_work _t *queue_tail;

pthread_mutex_t queue_lock;
pthread_cond_t queue_not_empty ;
pthread_cond_t queue_not_full;
pthread_cond_t queue_empty;

int queue_closed;
int shutdown;
} *threadpool_t;

void threadpool_init (threadpool_t *threadpoolp,
int num_worker_thre ads,
int max_queue_size,
int do_not_block_wh en_full);

int threadpool_add_ work(threadpool _t threadpool,
void *routine,
void *arg);

int threadpool_dest roy(threadpool_ t threadpoolp, int finish);

void threadpool_thre ad(threadpool_t threadpool);

In my server_threadp. c main method , I do following -

threadpool_t threadpool;

/* Allocate a pool data structure */
if ((threadpool = (threadpool_t) malloc(sizeof(s truct threadpool))) ==
NULL) {
perror("malloc" );
exit(1);
}

threadpool_add_ work function has following code -

if (threadpool->cur_queue_si ze == 0) {
threadpool->queue_tail = threadpool->queue_head =workp;
printf("Signal for pthread_cond_wa it waiting on
queue_not_empty :: %d\n", threadpool->queue_not_empt y);
pthread_cond_si gnal(&threadpoo l->queue_not_empt y);
} else {
(threadpool->queue_tail)-next = workp;
threadpool->queue_tail = workp;
}

For the first HTTP request, it will find threadpool->cur_queue_si ze ==
0 and hence will execute the IF block of the above code, but for any
subsequent request it will execute ELSE block above.

When I am sending 2nd request, ITS SEGFAULTING at
(threadpool->queue_tail)-next = workp;

I debugged it through gdb and when trying to print following -

(threadpool->queue_tail)-next

it throws - Can not access memory

Which i believe is because - Memory is not allocated to the structure
threadpool self element.

My Question is - When i allocate memory in the begining to threadpool
structure do i have to still allocate memory for any element which is
itself in this case. ? If so, how do i do that ?

Or is there something else which I am missing here ?

Thanks
Mahendra
Oct 17 '07 #1
5 2679
[You really did not need to post your question 3 times. Your posts
may not appear immediately, that's just the way it is. You may need
to wait a bit.]

Mahendra Kumar Kutare wrote:
I am trying to implement a webserver with boss-worker model thread
pool implementation -
My first reaction was, "oh no, another off-topic question," but in
fact yours is perfectly topical.

<snip>
/* Allocate a pool data structure */
if ((threadpool = (threadpool_t) malloc(sizeof(s truct threadpool))) ==
NULL) {
In C, casting malloc is not required and may hide a problem.
the preferred way is 'type *p = malloc(*p);'. That way, even if type
changes, the statement will remain safe. In your case, you could do

if ((threadpool = malloc(sizeof(* threadpool))) == /*...*/
perror("malloc" );
exit(1);
}

threadpool_add_ work function has following code -

if (threadpool->cur_queue_si ze == 0) {
threadpool->queue_tail = threadpool->queue_head =workp;
What's workp? Is it initialized to a valid threadpool?
printf("Signal for pthread_cond_wa it waiting on
queue_not_empty :: %d\n", threadpool->queue_not_empt y);
pthread_cond_si gnal(&threadpoo l->queue_not_empt y);
} else {
(threadpool->queue_tail)-next = workp;
^^^^^^^
Because if it isn't - BANG!
threadpool->queue_tail = workp;
}

For the first HTTP request, it will find threadpool->cur_queue_si ze ==
0 and hence will execute the IF block of the above code, but for any
subsequent request it will execute ELSE block above.

When I am sending 2nd request, ITS SEGFAULTING at
(threadpool->queue_tail)-next = workp;

I debugged it through gdb and when trying to print following -

(threadpool->queue_tail)-next

it throws - Can not access memory
If it does, then the implementors obviously could not spell.
It should be "cannot" (one word).
Which i believe is because - Memory is not allocated to the structure
threadpool self element.
Not so much not allocated as not initialized, I believe.
My Question is - When i allocate memory in the begining to threadpool
structure do i have to still allocate memory for any element which is
itself in this case. ? If so, how do i do that ?
I am not sure what you mean by "which is itself", but in general,
allocating alone leaves the value uninitialized. If the value happens
to be a struct, then its members are unitialized. Accessing an
uninitialized member may just yield garbage if it happens to be a
number, but if it is a pointer, the consequences may be more dire,
as you have experienced.
Or is there something else which I am missing here ?
Probably initializing your workp. Since I do not know where it came
from, I cannot be sure.

Peter
Oct 18 '07 #2

Thanks for your response. Sorry for multiple postings.

Now, coming back to the problem -

Code for the main method is as below -

*************** *************** *************** *************** **************

int main (int argc, char *argv[]) {

threadpool_t threadpool;

// Code to create INET socket
// bind, accept and listening socket code

/* Allocate a pool data structure */
if ((threadpool = (threadpool_t) malloc(sizeof(s truct
threadpool))) == NULL) {
perror("malloc" );
exit(1);
}

/* Initialize the thread pool */
threadpool_init (&threadpool, NUM_WORKER_THRE ADS, MAX_QUEUE_SIZE,
0);

while(1) {
/* Accepting connections from the client */
clilen = sizeof(cli_addr );
newsockfd = accept (sockfd, (struct sockaddr *)
&cli_addr, &clilen);
if (newsockfd < 0) {
error ("ERROR on accept");
}

threadpool_add_ work((void *) threadpool,
(*accept_reques ts), (void *) newsockfd);
}

return 0;
}
*************** *************** *************** *************** **************

void threadpool_init (threadpool_t *threadpoolp,
int num_worker_thre ads,
int max_queue_size,
int do_not_block_wh en_full) {

int i, rtn;
threadpool_t threadpool;

/* Allocate a pool data structure */
if ((threadpool = (threadpool_t) malloc(sizeof(s truct
threadpool))) == NULL) {
perror("malloc" );
exit(1);
}

/* Initialize the fields */
threadpool->num_threads = num_worker_thre ads;
threadpool->max_queue_si ze = max_queue_size;
threadpool->do_not_block_w hen_full = do_not_block_wh en_full;

if ((threadpool->threads = (pthread_t *)
malloc(sizeof(p thread_t) *num_worker_thr eads)) == NULL) {
perror("malloc" );
exit(1);
}

threadpool->cur_queue_si ze = 0;
threadpool->queue_head = NULL;
threadpool->queue_tail = NULL;

threadpool->queue_closed = 0;
threadpool->shutdown = 0;

if ((rtn = pthread_mutex_i nit(&(threadpoo l->queue_lock), NULL))
!= 0) {
fprintf (stderr, "pthread_mutex_ init %s", strerror(rtn));
exit(1);
}

if ((rtn = pthread_cond_in it(&(threadpool->queue_not_empt y),
NULL)) != 0) {
fprintf (stderr, "pthread_cond_i nit %s", strerror(rtn));
exit(1);
}

if ((rtn = pthread_cond_in it(&(threadpool->queue_not_full ),
NULL)) != 0) {
fprintf (stderr, "pthread_cond_i nit %s", strerror(rtn));
exit(1);
}

if ((rtn = pthread_cond_in it(&(threadpool->queue_empty) , NULL))
!= 0) {
fprintf (stderr, "pthread_cond_i nit %s", strerror(rtn));
exit(1);
}

/* Create threads */
for (i = 0; i != num_worker_thre ads; i++) {
if ((rtn = pthread_create( &(threadpool->threads[i]),
NULL, (void *) (*threadpool_th read),
(void *) threadpool)) != 0) {
fprintf (stderr, "pthread_cr eate %d", rtn);
exit(1);
}
}

*threadpoolp = threadpool;

*************** *************** *************** *************** **************

void threadpool_thre ad(threadpool_t threadpool) {

threadpool_work _t *my_workp;

for(;;) {
pthread_mutex_l ock(&(threadpoo l->queue_lock)) ;

printf("Cur queue size:: %d\n",
threadpool->cur_queue_size );
printf("Max queue size:: %d\n",
threadpool->max_queue_size );
printf("Cur shutdown :: %d\n",
(!(threadpool->shutdown)));
while((threadpo ol->cur_queue_si ze == 0) &&
(!threadpool->shutdown)) {
printf("Waiting for pthread_cond_wa it
queue_not_empty :: %d\n", threadpool->queue_not_empt y);

pthread_cond_wa it(&(threadpool->queue_not_empt y),
&(threadpool->queue_lock)) ;
}

if (threadpool->shutdown) {
pthread_mutex_u nlock(&(threadp ool->queue_lock)) ;
pthread_exit(NU LL);
}

my_workp = threadpool->queue_head;
threadpool->cur_queue_si ze--;
if (threadpool->cur_queue_si ze == 0) {
threadpool->queue_head = threadpool->queue_tail = NULL;
} else {
threadpool->queue_head = my_workp->next;
}

if ((!threadpool->do_not_block_w hen_full) &&
(threadpool->cur_queue_si ze =
(threadpool->max_queue_si ze -1))) {

pthread_cond_si gnal(&(threadpo ol->queue_not_full ));
}

if (threadpool->cur_queue_si ze == 0) {
pthread_cond_si gnal(&(threadpo ol->queue_empty) );
}

pthread_mutex_u nlock(&(threadp ool->queue_lock)) ;
(*(my_workp->routine))(my_w orkp->arg);
free(my_workp);
}
}

*************** *************** *************** *************** **************
int threadpool_add_ work(threadpool _t threadpool, void *routine, void
*arg) {

threadpool_work _t *workp;
pthread_mutex_l ock(&threadpool->queue_lock);

if((threadpool->cur_queue_si ze == threadpool->max_queue_size ) &&
threadpool->do_not_block_w hen_full) {
pthread_mutex_u nlock(&threadpo ol->queue_lock);
return -1;
}

while((threadpo ol->cur_queue_si ze ==
threadpool->max_queue_size ) &&
((threadpool->shutdown || threadpool->queue_closed)) ) {

printf("Waiting for pthread_cond_wa it queue_not_full: :
%d\n", threadpool->queue_not_full );
pthread_cond_wa it(&threadpool->queue_not_full ,
&threadpool->queue_lock);
}

if(threadpool->shutdown || threadpool->queue_closed ) {
printf("Threadp ool_add_work::U nlocking mutex:: %d\n",
threadpool->queue_lock);
pthread_mutex_u nlock(&threadpo ol->queue_lock);
return -1;
}
/* Allocate work structure */
workp = (threadpool_wor k_t *) malloc(sizeof(t hreadpool_work_ t));
workp->routine = routine;
workp->arg = arg;
workp->next = NULL;

if (threadpool->cur_queue_si ze == 0) {
threadpool->queue_tail = threadpool->queue_head =workp;
printf("Signal for pthread_cond_wa it waiting on queue_not_empty :: %d\n", threadpool->queue_not_empt y);
pthread_cond_si gnal(&threadpoo l->queue_not_empt y);
} else {
(threadpool->queue_tail)-next = workp;
threadpool->queue_tail = workp;
}
threadpool->cur_queue_size ++;
pthread_mutex_u nlock(&threadpo ol->queue_lock);
return 1;
}
*************** *************** *************** *************** **************

The header file threadpool.h looks as below -

*************** *************** *************** *************** **************
typedef struct threadpool_work {
void (*routine) ();
void *arg;
struct threadpool_work *next;
} threadpool_work _t;

typedef struct threadpool {
/* Pool Characteristics */
int num_threads;
int max_queue_size;

int do_not_block_wh en_full;
pthread_t *threads;
int cur_queue_size;
threadpool_work _t *queue_head;
threadpool_work _t *queue_tail;

pthread_mutex_t queue_lock;
pthread_cond_t queue_not_empty ;
pthread_cond_t queue_not_full;
pthread_cond_t queue_empty;

int queue_closed;
int shutdown;
} *threadpool_t;

void threadpool_init (threadpool_t *threadpoolp,
int num_worker_thre ads,
int max_queue_size,
int do_not_block_wh en_full);

int threadpool_add_ work(threadpool _t threadpool,
void *routine,
void *arg);

int threadpool_dest roy(threadpool_ t threadpoolp, int finish);

void threadpool_thre ad(threadpool_t threadpool);
*************** *************** *************** *************** **************

Now as can be seen "workp" is allocated structure in the above code and
initialized the 'routine' to routine, 'arg' to arg and 'next' a pointer
to NULL respectively.
I am not sure what you mean by "which is itself", but in general,
allocating alone leaves the value uninitialized. If the value happens
to be a struct, then its members are unitialized. Accessing an
uninitialized member may just yield garbage if it happens to be a
number, but if it is a pointer, the consequences may be more dire,
as you have experienced.
Now i see your point that 'next' which itself is a pointer to struct and
its members are not initialized. But threadpool->queue_tail which has
struct element 'next' is NOT initialized to which I am trying to
allocate 'workp'.

This threadpool is passed in the declared in the beginning of the main
method and then allocated before calling thread_init(... .).

So how do I initialize

(threadpool->queue_tail) which points to a structure
threadpool_work _t and whose element - 'next' is pointer to
threadpool_work _t ?

Thanks
Mahendra
Peter Pichler wrote:
[You really did not need to post your question 3 times. Your posts
may not appear immediately, that's just the way it is. You may need
to wait a bit.]

Mahendra Kumar Kutare wrote:
>I am trying to implement a webserver with boss-worker model thread
pool implementation -

My first reaction was, "oh no, another off-topic question," but in
fact yours is perfectly topical.

<snip>
>/* Allocate a pool data structure */
if ((threadpool = (threadpool_t) malloc(sizeof(s truct threadpool))) ==
NULL) {

In C, casting malloc is not required and may hide a problem.
the preferred way is 'type *p = malloc(*p);'. That way, even if type
changes, the statement will remain safe. In your case, you could do

if ((threadpool = malloc(sizeof(* threadpool))) == /*...*/
> perror("malloc" );
exit(1);
}

threadpool_add _work function has following code -

if (threadpool->cur_queue_si ze == 0) {
threadpool->queue_tail = threadpool->queue_head =workp;

What's workp? Is it initialized to a valid threadpool?
> printf("Signal for pthread_cond_wa it waiting on
queue_not_empt y:: %d\n", threadpool->queue_not_empt y);
pthread_cond_si gnal(&threadpoo l->queue_not_empt y);
} else {
(threadpool->queue_tail)-next = workp;
^^^^^^^
Because if it isn't - BANG!
> threadpool->queue_tail = workp;
}

For the first HTTP request, it will find threadpool->cur_queue_si ze ==
0 and hence will execute the IF block of the above code, but for any
subsequent request it will execute ELSE block above.

When I am sending 2nd request, ITS SEGFAULTING at
(threadpool->queue_tail)-next = workp;

I debugged it through gdb and when trying to print following -

(threadpool->queue_tail)-next

it throws - Can not access memory

If it does, then the implementors obviously could not spell.
It should be "cannot" (one word).
>Which i believe is because - Memory is not allocated to the structure
threadpool self element.

Not so much not allocated as not initialized, I believe.
>My Question is - When i allocate memory in the begining to threadpool
structure do i have to still allocate memory for any element which is
itself in this case. ? If so, how do i do that ?

I am not sure what you mean by "which is itself", but in general,
allocating alone leaves the value uninitialized. If the value happens
to be a struct, then its members are unitialized. Accessing an
uninitialized member may just yield garbage if it happens to be a
number, but if it is a pointer, the consequences may be more dire,
as you have experienced.
>Or is there something else which I am missing here ?

Probably initializing your workp. Since I do not know where it came
from, I cannot be sure.

Peter
Oct 18 '07 #3
Mahendra Kumar Kutare wrote:
>
Thanks for your response. Sorry for multiple postings.

Now, coming back to the problem -
3 issues stand out for me:

1) You don't check the return value of malloc() when allocating
workp in threadpool_add_ work(). Granted, you don't immediately die
touching it... but you should check.

2) As previously noted, make sure you've included stdlib.h and get
rid of the malloc() casting.

3) I think your problem is this line in threadpool_thre ad():
if ((!threadpool->do_not_block_w hen_full) &&
(threadpool->cur_queue_si ze =
(threadpool->max_queue_si ze -1))) {

If the threadpool is not marked as "do_not_block_w hen_full", you're
always setting the size of the circular queue to be the max - 1
[because I think this is a typo where you have "=" instead of "=="].
As a result, the queue will erroneously report it has elements when
you've in fact removed them all... hence you derefence the NULL pointer
at the tail of the queue and die.

Since your main() does mark the threadpool via threadpool_init with
0 for the do_not_block_wh en_full state... this seems consistent to me.

Don
Code for the main method is as below -

*************** *************** *************** *************** **************

int main (int argc, char *argv[]) {

threadpool_t threadpool;

// Code to create INET socket
// bind, accept and listening socket code

/* Allocate a pool data structure */
if ((threadpool = (threadpool_t) malloc(sizeof(s truct
threadpool))) == NULL) {
perror("malloc" );
exit(1);
}

/* Initialize the thread pool */
threadpool_init (&threadpool, NUM_WORKER_THRE ADS, MAX_QUEUE_SIZE,
0);

while(1) {
/* Accepting connections from the client */
clilen = sizeof(cli_addr );
newsockfd = accept (sockfd, (struct sockaddr *)
&cli_addr, &clilen);
if (newsockfd < 0) {
error ("ERROR on accept");
}

threadpool_add_ work((void *) threadpool,
(*accept_reques ts), (void *) newsockfd);
}

return 0;
}
*************** *************** *************** *************** **************

void threadpool_init (threadpool_t *threadpoolp,
int num_worker_thre ads,
int max_queue_size,
int do_not_block_wh en_full) {

int i, rtn;
threadpool_t threadpool;

/* Allocate a pool data structure */
if ((threadpool = (threadpool_t) malloc(sizeof(s truct
threadpool))) == NULL) {
perror("malloc" );
exit(1);
}

/* Initialize the fields */
threadpool->num_threads = num_worker_thre ads;
threadpool->max_queue_si ze = max_queue_size;
threadpool->do_not_block_w hen_full = do_not_block_wh en_full;

if ((threadpool->threads = (pthread_t *)
malloc(sizeof(p thread_t) *num_worker_thr eads)) == NULL) {
perror("malloc" );
exit(1);
}

threadpool->cur_queue_si ze = 0;
threadpool->queue_head = NULL;
threadpool->queue_tail = NULL;

threadpool->queue_closed = 0;
threadpool->shutdown = 0;

if ((rtn = pthread_mutex_i nit(&(threadpoo l->queue_lock), NULL))
!= 0) {
fprintf (stderr, "pthread_mutex_ init %s", strerror(rtn));
exit(1);
}

if ((rtn = pthread_cond_in it(&(threadpool->queue_not_empt y),
NULL)) != 0) {
fprintf (stderr, "pthread_cond_i nit %s", strerror(rtn));
exit(1);
}

if ((rtn = pthread_cond_in it(&(threadpool->queue_not_full ),
NULL)) != 0) {
fprintf (stderr, "pthread_cond_i nit %s", strerror(rtn));
exit(1);
}

if ((rtn = pthread_cond_in it(&(threadpool->queue_empty) , NULL))
!= 0) {
fprintf (stderr, "pthread_cond_i nit %s", strerror(rtn));
exit(1);
}

/* Create threads */
for (i = 0; i != num_worker_thre ads; i++) {
if ((rtn = pthread_create( &(threadpool->threads[i]),
NULL, (void *) (*threadpool_th read),
(void *) threadpool)) != 0) {
fprintf (stderr, "pthread_cr eate %d", rtn);
exit(1);
}
}

*threadpoolp = threadpool;

*************** *************** *************** *************** **************

void threadpool_thre ad(threadpool_t threadpool) {

threadpool_work _t *my_workp;

for(;;) {
pthread_mutex_l ock(&(threadpoo l->queue_lock)) ;

printf("Cur queue size:: %d\n",
threadpool->cur_queue_size );
printf("Max queue size:: %d\n",
threadpool->max_queue_size );
printf("Cur shutdown :: %d\n",
(!(threadpool->shutdown)));
while((threadpo ol->cur_queue_si ze == 0) &&
(!threadpool->shutdown)) {
printf("Waiting for pthread_cond_wa it
queue_not_empty :: %d\n", threadpool->queue_not_empt y);

pthread_cond_wa it(&(threadpool->queue_not_empt y),
&(threadpool->queue_lock)) ;
}

if (threadpool->shutdown) {
pthread_mutex_u nlock(&(threadp ool->queue_lock)) ;
pthread_exit(NU LL);
}

my_workp = threadpool->queue_head;
threadpool->cur_queue_si ze--;
if (threadpool->cur_queue_si ze == 0) {
threadpool->queue_head = threadpool->queue_tail = NULL;
} else {
threadpool->queue_head = my_workp->next;
}

if ((!threadpool->do_not_block_w hen_full) &&
(threadpool->cur_queue_si ze =
(threadpool->max_queue_si ze -1))) {

pthread_cond_si gnal(&(threadpo ol->queue_not_full ));
}

if (threadpool->cur_queue_si ze == 0) {
pthread_cond_si gnal(&(threadpo ol->queue_empty) );
}

pthread_mutex_u nlock(&(threadp ool->queue_lock)) ;
(*(my_workp->routine))(my_w orkp->arg);
free(my_workp);
}
}

*************** *************** *************** *************** **************
int threadpool_add_ work(threadpool _t threadpool, void *routine, void
*arg) {

threadpool_work _t *workp;
pthread_mutex_l ock(&threadpool->queue_lock);

if((threadpool->cur_queue_si ze == threadpool->max_queue_size ) &&
threadpool->do_not_block_w hen_full) {
pthread_mutex_u nlock(&threadpo ol->queue_lock);
return -1;
}

while((threadpo ol->cur_queue_si ze ==
threadpool->max_queue_size ) &&
((threadpool->shutdown || threadpool->queue_closed)) ) {

printf("Waiting for pthread_cond_wa it queue_not_full: :
%d\n", threadpool->queue_not_full );
pthread_cond_wa it(&threadpool->queue_not_full ,
&threadpool->queue_lock);
}

if(threadpool->shutdown || threadpool->queue_closed ) {
printf("Threadp ool_add_work::U nlocking mutex:: %d\n",
threadpool->queue_lock);
pthread_mutex_u nlock(&threadpo ol->queue_lock);
return -1;
}
> /* Allocate work structure */
workp = (threadpool_wor k_t *) malloc(sizeof(t hreadpool_work_ t));
workp->routine = routine;
workp->arg = arg;
workp->next = NULL;

if (threadpool->cur_queue_si ze == 0) {
threadpool->queue_tail = threadpool->queue_head =workp;
printf("Signal for pthread_cond_wa it waiting on
queue_not_empt y:: %d\n", threadpool->queue_not_empt y);
pthread_cond_si gnal(&threadpoo l->queue_not_empt y);
} else {
(threadpool->queue_tail)-next = workp;
threadpool->queue_tail = workp;
}

threadpool->cur_queue_size ++;
pthread_mutex_u nlock(&threadpo ol->queue_lock);
return 1;
}
*************** *************** *************** *************** **************

The header file threadpool.h looks as below -

*************** *************** *************** *************** **************
typedef struct threadpool_work {
void (*routine) ();
void *arg;
struct threadpool_work *next;
} threadpool_work _t;

typedef struct threadpool {
/* Pool Characteristics */
int num_threads;
int max_queue_size;

int do_not_block_wh en_full;
pthread_t *threads;
int cur_queue_size;
threadpool_work _t *queue_head;
threadpool_work _t *queue_tail;

pthread_mutex_t queue_lock;
pthread_cond_t queue_not_empty ;
pthread_cond_t queue_not_full;
pthread_cond_t queue_empty;

int queue_closed;
int shutdown;
} *threadpool_t;

void threadpool_init (threadpool_t *threadpoolp,
int num_worker_thre ads,
int max_queue_size,
int do_not_block_wh en_full);

int threadpool_add_ work(threadpool _t threadpool,
void *routine,
void *arg);

int threadpool_dest roy(threadpool_ t threadpoolp, int finish);

void threadpool_thre ad(threadpool_t threadpool);
*************** *************** *************** *************** **************

Now as can be seen "workp" is allocated structure in the above code and
initialized the 'routine' to routine, 'arg' to arg and 'next' a pointer
to NULL respectively.
I am not sure what you mean by "which is itself", but in general,
allocating alone leaves the value uninitialized. If the value happens
to be a struct, then its members are unitialized. Accessing an
uninitialized member may just yield garbage if it happens to be a
number, but if it is a pointer, the consequences may be more dire,
as you have experienced.

Now i see your point that 'next' which itself is a pointer to struct and
its members are not initialized. But threadpool->queue_tail which has
struct element 'next' is NOT initialized to which I am trying to
allocate 'workp'.

This threadpool is passed in the declared in the beginning of the main
method and then allocated before calling thread_init(... .).

So how do I initialize

(threadpool->queue_tail) which points to a structure
threadpool_work _t and whose element - 'next' is pointer to
threadpool_work _t ?

Thanks
Mahendra
Peter Pichler wrote:
>[You really did not need to post your question 3 times. Your posts
may not appear immediately, that's just the way it is. You may need
to wait a bit.]

Mahendra Kumar Kutare wrote:
>>I am trying to implement a webserver with boss-worker model thread
pool implementation -

My first reaction was, "oh no, another off-topic question," but in
fact yours is perfectly topical.

<snip>
>>/* Allocate a pool data structure */
if ((threadpool = (threadpool_t) malloc(sizeof(s truct threadpool))) ==
NULL) {

In C, casting malloc is not required and may hide a problem.
the preferred way is 'type *p = malloc(*p);'. That way, even if type
changes, the statement will remain safe. In your case, you could do

if ((threadpool = malloc(sizeof(* threadpool))) == /*...*/
>> perror("malloc" );
exit(1);
}

threadpool_ad d_work function has following code -

if (threadpool->cur_queue_si ze == 0) {
threadpool->queue_tail = threadpool->queue_head =workp;

What's workp? Is it initialized to a valid threadpool?
>> printf("Signal for pthread_cond_wa it waiting on
queue_not_emp ty:: %d\n", threadpool->queue_not_empt y);
pthread_cond_si gnal(&threadpoo l->queue_not_empt y);
} else {
(threadpool->queue_tail)-next = workp;
^^^^^^^
Because if it isn't - BANG!
>> threadpool->queue_tail = workp;
}

For the first HTTP request, it will find threadpool->cur_queue_si ze ==
0 and hence will execute the IF block of the above code, but for any
subsequent request it will execute ELSE block above.

When I am sending 2nd request, ITS SEGFAULTING at
(threadpool->queue_tail)-next = workp;

I debugged it through gdb and when trying to print following -

(threadpool->queue_tail)-next

it throws - Can not access memory

If it does, then the implementors obviously could not spell.
It should be "cannot" (one word).
>>Which i believe is because - Memory is not allocated to the structure
threadpool self element.

Not so much not allocated as not initialized, I believe.
>>My Question is - When i allocate memory in the begining to threadpool
structure do i have to still allocate memory for any element which is
itself in this case. ? If so, how do i do that ?

I am not sure what you mean by "which is itself", but in general,
allocating alone leaves the value uninitialized. If the value happens
to be a struct, then its members are unitialized. Accessing an
uninitialize d member may just yield garbage if it happens to be a
number, but if it is a pointer, the consequences may be more dire,
as you have experienced.
>>Or is there something else which I am missing here ?

Probably initializing your workp. Since I do not know where it came
from, I cannot be sure.

Peter
Oct 18 '07 #4

Hi Don and Peter,

Thanks for your responses.

I have modified my code to reflect 1 and 2.

The biggest issue was as mentioned in point 3. Rather than comparing (==) the
code was equating (=) that made the code work well.

I executed the code with the above changes and able to read the static html
files from webserver client code using command - GET /index.html HTTP/1.1

I have a further doubt about as following -

A) With above changes, the code did not SEGFAULT and run well. The code to
process work is as below -

I would like to know any improvements which can be done on code below specially
'accept_request s' and 'process_reques t' method. This code is currently working fine.

int main (int argc, char *argv[]) {

//////////
Code to create socket, bind and listen for incoming connections
//////////
/* Keep waiting for connections */
while(1) {
/* Accepting connections from the client */
clilen = sizeof(cli_addr );
newsockfd = accept (sockfd, (struct sockaddr *) &cli_addr,
&clilen);
if (newsockfd < 0) {
error ("ERROR on accept");
}
/* Add work to the queue for threads to work upon */
threadpool_add_ work((void *) threadp, (*accept_reques ts), (void
*) newsockfd);
}

//////////
}

void *accept_request s(void *params) {

int socket_fd = (int) params;
pthread_t tid = pthread_self();

/* Take the data from socket and pass it for processing */
process_request s(socket_fd);

printf("Done processing: %d\n", tid);
pthread_exit(NU LL);
}

void process_request s(int socket_fd) {

int n, ret;
char buffer[256];
char line[100], method[100], path[100], protocol[100];
char *file;
FILE *fp;
size_t bytes_read;

/* Initializing the buffer */
bzero(buffer, 256);
/* Reading from socket */
n = read (socket_fd, buffer, 255);
if (n < 0) {
error("ERROR reading from socket");
}

printf("Client communication message:: %s\n", buffer);

ret = sscanf(buffer, "%[^ ] %[^ ] %[^ ]", method, path, protocol);
if (ret != 3) {
printf(" Bad Request : Can't parse request ");
}
file = &(path[1]);
fp = fopen(file, "r");
if (fp == NULL) {
error (" Could not open the file ");
} else {
bzero(buffer, 256);
bytes_read = fread(buffer, sizeof(buffer), 1, fp);

}

write(socket_fd , buffer, 256);
close(socket_fd );
}

B) I have typedefs in header file -

1) threadpool_t which is a pointer variable - pointer to threadpool structure.
>typedef struct threadpool {
/* Pool Characteristics */
int num_threads;
int max_queue_size;

int do_not_block_wh en_full;
pthread_t *threads;
int cur_queue_size;
threadpool_work _t *queue_head;
threadpool_work _t *queue_tail;

pthread_mutex_t queue_lock;
pthread_cond_t queue_not_empty ;
pthread_cond_t queue_not_full;
pthread_cond_t queue_empty;

int queue_closed;
int shutdown;
} *threadpool_t;
2) I declare in my (current modified code) main method -
threadpool_t threadp;

which by header definition above =threadp is of type threadpool_t (typedef),
which is a pointer to struct threadpool.

This 'threadp' variable is malloced before threadpool_init is called as -

if ((threadp = malloc(sizeof(t hreadp))) == NULL) {
perror("malloc" );
exit(1);
}

Hence to threadpool_init function that has following signature -

void threadpool_init (threadpool_t *threadp,
int num_worker_thre ads,
int max_queue_size,
int do_not_block_wh en_full);

I pass arg1 as '&threadp' - i.e. I am passing the address of memory location of
'threadp' - i.e. address of memory location of struct-type 'threadpool'

But, inside 'threadpool_ini t' method there is local 'threadP' variable of type
'threadpool_t' as -
threadpool_t threadP;

Here again, I malloced the threadP of structure type 'threadpool_t' as -

if ((threadP = malloc(sizeof(* threadP))) == NULL) {
perror("malloc" );
exit(1);
}

It can be seen that malloc() assignment for 'threadP' has <b>'*threadP' </bas
parameter for sizeof() method. However compare this with malloc assignment of
'threadp' and it can seen that <b>'threadp'</bis passed as parameter for
sizeof() method. So essentially once I am passing pointer variable and in
another case just the variable of type 'threadpool_t'.

I tried passing just the variable of type 'threadpool_t' i.e. 'threadP' in
sizeof() function of malloc code above but that causes program to hang indefinitely.

I am not sure, as why is this difference of behaviour in mallocing ? Why can not
the 2nd mallocing work as following -

if ((threadP = malloc(sizeof(t hreadP))) == NULL) {
perror("malloc" );
exit(1);
}

It should be noticed that that finally in 'threadpool_ini t' function 'threadP'
is assigned to '*threadp' as -

====>>>*threadp = threadP; // In the last line of 'threadpool_ini t' function

Appreciate your help on this so far.

Thanks
Mahendra

Don Morris wrote:
Mahendra Kumar Kutare wrote:
>>
Thanks for your response. Sorry for multiple postings.

Now, coming back to the problem -

3 issues stand out for me:

1) You don't check the return value of malloc() when allocating
workp in threadpool_add_ work(). Granted, you don't immediately die
touching it... but you should check.

2) As previously noted, make sure you've included stdlib.h and get
rid of the malloc() casting.

3) I think your problem is this line in threadpool_thre ad():
if ((!threadpool->do_not_block_w hen_full) &&
(threadpool->cur_queue_si ze =
(threadpool->max_queue_si ze -1))) {

If the threadpool is not marked as "do_not_block_w hen_full", you're
always setting the size of the circular queue to be the max - 1
[because I think this is a typo where you have "=" instead of "=="].
As a result, the queue will erroneously report it has elements when
you've in fact removed them all... hence you derefence the NULL pointer
at the tail of the queue and die.

Since your main() does mark the threadpool via threadpool_init with
0 for the do_not_block_wh en_full state... this seems consistent to me.

Don
>Code for the main method is as below -

************** *************** *************** *************** ***************
int main (int argc, char *argv[]) {

threadpool_t threadpool;
// Code to create INET socket
// bind, accept and listening socket code

/* Allocate a pool data structure */
if ((threadpool = (threadpool_t) malloc(sizeof(s truct
threadpool))) == NULL) {
perror("malloc" );
exit(1);
}

/* Initialize the thread pool */
threadpool_init (&threadpool, NUM_WORKER_THRE ADS, MAX_QUEUE_SIZE,
0);

while(1) {
/* Accepting connections from the client */
clilen = sizeof(cli_addr );
newsockfd = accept (sockfd, (struct sockaddr *)
&cli_addr, &clilen);
if (newsockfd < 0) {
error ("ERROR on accept");
}

threadpool_add_ work((void *) threadpool,
(*accept_reques ts), (void *) newsockfd);
}

return 0;
}
************** *************** *************** *************** ***************
void threadpool_init (threadpool_t *threadpoolp,
int num_worker_thre ads,
int max_queue_size,
int do_not_block_wh en_full) {

int i, rtn;
threadpool_t threadpool;

/* Allocate a pool data structure */
if ((threadpool = (threadpool_t) malloc(sizeof(s truct
threadpool))) == NULL) {
perror("malloc" );
exit(1);
}

/* Initialize the fields */
threadpool->num_threads = num_worker_thre ads;
threadpool->max_queue_si ze = max_queue_size;
threadpool->do_not_block_w hen_full = do_not_block_wh en_full;

if ((threadpool->threads = (pthread_t *)
malloc(sizeof(p thread_t) *num_worker_thr eads)) == NULL) {
perror("malloc" );
exit(1);
}

threadpool->cur_queue_si ze = 0;
threadpool->queue_head = NULL;
threadpool->queue_tail = NULL;

threadpool->queue_closed = 0;
threadpool->shutdown = 0;

if ((rtn = pthread_mutex_i nit(&(threadpoo l->queue_lock), NULL))
!= 0) {
fprintf (stderr, "pthread_mutex_ init %s", strerror(rtn));
exit(1);
}

if ((rtn = pthread_cond_in it(&(threadpool->queue_not_empt y),
NULL)) != 0) {
fprintf (stderr, "pthread_cond_i nit %s", strerror(rtn));
exit(1);
}

if ((rtn = pthread_cond_in it(&(threadpool->queue_not_full ),
NULL)) != 0) {
fprintf (stderr, "pthread_cond_i nit %s", strerror(rtn));
exit(1);
}

if ((rtn = pthread_cond_in it(&(threadpool->queue_empty) , NULL))
!= 0) {
fprintf (stderr, "pthread_cond_i nit %s", strerror(rtn));
exit(1);
}

/* Create threads */
for (i = 0; i != num_worker_thre ads; i++) {
if ((rtn = pthread_create( &(threadpool->threads[i]),
NULL, (void *) (*threadpool_th read),
(void *) threadpool)) != 0) {
fprintf (stderr, "pthread_cr eate %d", rtn);
exit(1);
}
}

*threadpoolp = threadpool;

************** *************** *************** *************** ***************
void threadpool_thre ad(threadpool_t threadpool) {

threadpool_work _t *my_workp;

for(;;) {
pthread_mutex_l ock(&(threadpoo l->queue_lock)) ;

printf("Cur queue size:: %d\n",
threadpool->cur_queue_size );
printf("Max queue size:: %d\n",
threadpool->max_queue_size );
printf("Cur shutdown :: %d\n",
(!(threadpool->shutdown)));
while((threadpo ol->cur_queue_si ze == 0) &&
(!threadpool->shutdown)) {
printf("Waiting for pthread_cond_wa it
queue_not_empty :: %d\n", threadpool->queue_not_empt y);

pthread_cond_wa it(&(threadpool->queue_not_empt y),
&(threadpool->queue_lock)) ;
}

if (threadpool->shutdown) {
pthread_mutex_u nlock(&(threadp ool->queue_lock)) ;
pthread_exit(NU LL);
}

my_workp = threadpool->queue_head;
threadpool->cur_queue_si ze--;
if (threadpool->cur_queue_si ze == 0) {
threadpool->queue_head = threadpool->queue_tail = NULL;
} else {
threadpool->queue_head = my_workp->next;
}

if ((!threadpool->do_not_block_w hen_full) &&
(threadpool->cur_queue_si ze =
(threadpool->max_queue_si ze -1))) {

pthread_cond_si gnal(&(threadpo ol->queue_not_full ));
}

if (threadpool->cur_queue_si ze == 0) {
pthread_cond_si gnal(&(threadpo ol->queue_empty) );
}

pthread_mutex_u nlock(&(threadp ool->queue_lock)) ;
(*(my_workp->routine))(my_w orkp->arg);
free(my_workp);
}
}

************** *************** *************** *************** ***************

int threadpool_add_ work(threadpool _t threadpool, void *routine, void
*arg) {

threadpool_work _t *workp;
pthread_mutex_l ock(&threadpool->queue_lock);

if((threadpool->cur_queue_si ze == threadpool->max_queue_size ) &&
threadpool->do_not_block_w hen_full) {
pthread_mutex_u nlock(&threadpo ol->queue_lock);
return -1;
}

while((threadpo ol->cur_queue_si ze ==
threadpool->max_queue_size ) &&
((threadpool->shutdown || threadpool->queue_closed)) ) {

printf("Waiting for pthread_cond_wa it queue_not_full: :
%d\n", threadpool->queue_not_full );
pthread_cond_wa it(&threadpool->queue_not_full ,
&threadpool->queue_lock);
}

if(threadpool->shutdown || threadpool->queue_closed ) {
printf("Threadp ool_add_work::U nlocking mutex:: %d\n",
threadpool->queue_lock);
pthread_mutex_u nlock(&threadpo ol->queue_lock);
return -1;
}
>> /* Allocate work structure */
workp = (threadpool_wor k_t *) malloc(sizeof(t hreadpool_work_ t));
workp->routine = routine;
workp->arg = arg;
workp->next = NULL;

if (threadpool->cur_queue_si ze == 0) {
threadpool->queue_tail = threadpool->queue_head =workp;
printf("Signal for pthread_cond_wa it waiting on
queue_not_emp ty:: %d\n", threadpool->queue_not_empt y);
pthread_cond_si gnal(&threadpoo l->queue_not_empt y);
} else {
(threadpool->queue_tail)-next = workp;
threadpool->queue_tail = workp;
}

threadpool->cur_queue_size ++;
pthread_mutex_u nlock(&threadpo ol->queue_lock);
return 1;
}
************** *************** *************** *************** ***************
The header file threadpool.h looks as below -

************** *************** *************** *************** ***************

typedef struct threadpool_work {
void (*routine) ();
void *arg;
struct threadpool_work *next;
} threadpool_work _t;

typedef struct threadpool {
/* Pool Characteristics */
int num_threads;
int max_queue_size;

int do_not_block_wh en_full;
pthread_t *threads;
int cur_queue_size;
threadpool_work _t *queue_head;
threadpool_work _t *queue_tail;

pthread_mutex_t queue_lock;
pthread_cond_t queue_not_empty ;
pthread_cond_t queue_not_full;
pthread_cond_t queue_empty;

int queue_closed;
int shutdown;
} *threadpool_t;

void threadpool_init (threadpool_t *threadpoolp,
int num_worker_thre ads,
int max_queue_size,
int do_not_block_wh en_full);

int threadpool_add_ work(threadpool _t threadpool,
void *routine,
void *arg);

int threadpool_dest roy(threadpool_ t threadpoolp, int finish);

void threadpool_thre ad(threadpool_t threadpool);
************** *************** *************** *************** ***************
Now as can be seen "workp" is allocated structure in the above code
and initialized the 'routine' to routine, 'arg' to arg and 'next' a
pointer to NULL respectively.
> I am not sure what you mean by "which is itself", but in general,
allocating alone leaves the value uninitialized. If the value happens
to be a struct, then its members are unitialized. Accessing an
uninitialized member may just yield garbage if it happens to be a
number, but if it is a pointer, the consequences may be more dire,
as you have experienced.

Now i see your point that 'next' which itself is a pointer to struct
and its members are not initialized. But threadpool->queue_tail which
has struct element 'next' is NOT initialized to which I am trying to
allocate 'workp'.

This threadpool is passed in the declared in the beginning of the main
method and then allocated before calling thread_init(... .).

So how do I initialize

(threadpool->queue_tail) which points to a structure
threadpool_work _t and whose element - 'next' is pointer to
threadpool_wor k_t ?

Thanks
Mahendra
Peter Pichler wrote:
>>[You really did not need to post your question 3 times. Your posts
may not appear immediately, that's just the way it is. You may need
to wait a bit.]

Mahendra Kumar Kutare wrote:

I am trying to implement a webserver with boss-worker model thread
pool implementation -

My first reaction was, "oh no, another off-topic question," but in
fact yours is perfectly topical.

<snip>

/* Allocate a pool data structure */
if ((threadpool = (threadpool_t) malloc(sizeof(s truct threadpool))) ==
NULL) {

In C, casting malloc is not required and may hide a problem.
the preferred way is 'type *p = malloc(*p);'. That way, even if type
changes, the statement will remain safe. In your case, you could do

if ((threadpool = malloc(sizeof(* threadpool))) == /*...*/

perror("malloc" );
exit(1);
}

threadpool_a dd_work function has following code -

if (threadpool->cur_queue_si ze == 0) {
threadpool->queue_tail = threadpool->queue_head =workp;

What's workp? Is it initialized to a valid threadpool?

printf("Signal for pthread_cond_wa it waiting on
queue_not_em pty:: %d\n", threadpool->queue_not_empt y);
pthread_cond_si gnal(&threadpoo l->queue_not_empt y);
} else {
(threadpool->queue_tail)-next = workp;
^^^^^^^
Because if it isn't - BANG!

threadpool->queue_tail = workp;
}

For the first HTTP request, it will find threadpool->cur_queue_si ze ==
0 and hence will execute the IF block of the above code, but for any
subsequent request it will execute ELSE block above.

When I am sending 2nd request, ITS SEGFAULTING at
(threadpoo l->queue_tail)-next = workp;

I debugged it through gdb and when trying to print following -

(threadpoo l->queue_tail)-next

it throws - Can not access memory

If it does, then the implementors obviously could not spell.
It should be "cannot" (one word).

Which i believe is because - Memory is not allocated to the structure
threadpool self element.

Not so much not allocated as not initialized, I believe.

My Question is - When i allocate memory in the begining to threadpool
structure do i have to still allocate memory for any element which is
itself in this case. ? If so, how do i do that ?

I am not sure what you mean by "which is itself", but in general,
allocating alone leaves the value uninitialized. If the value happens
to be a struct, then its members are unitialized. Accessing an
uninitializ ed member may just yield garbage if it happens to be a
number, but if it is a pointer, the consequences may be more dire,
as you have experienced.

Or is there something else which I am missing here ?

Probably initializing your workp. Since I do not know where it came
from, I cannot be sure.

Peter
Oct 19 '07 #5
"Peter Pichler" <us****@pichler .co.ukschrieb im Newsbeitrag
news:47******** **@mk-nntp-2.news.uk.tisca li.com...
Mahendra Kumar Kutare wrote:
>I have a further doubt about as following -

Where I live, a "doubt" is an expressed disbelief: "I doubt I can drink
all night as I used to when I was young." "I have doubts about usefulness
of gets()."

Did you mean "question" or "uncertaint y"?
This seems to be a common expression in India and should mean what you
guessed it might.

Bye, Jojo
Oct 20 '07 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
532
by: Michael Sgier | last post by:
Hello i get the error: Segmentation fault. The debugger stopped at the last of the following lines: // This stores the texture array for each of the textures assigned to this model unsigned int m_Textures;
8
2148
by: James Leddy | last post by:
Hello, I am making a program that encrypts and compresses plain text and indexes them by date. Needless to say, I have many alloc(), realloc(), calloc(), and free() calls. There are also double pointers all over the place. The program works fine except for one tiny detail. Every time I try to extract a file, the program terminates with a segmentation fault. I used
4
2120
by: Marcia Hon | last post by:
Hi, I am trying to run a program except I get the following segmentation fault. I don't know how to solve it. Please if you know could you please help. Thanks, Marcia Program received signal SIGSEGV, Segmentation fault.
9
2024
by: Narendran Kumaraguru Nathan | last post by:
Hi all, I am fairly experianced in C. I am writing a program in which I'm getting a segmentation fault. The problem is that it is getting the segmentation fault when executing calloc. I tried debugging it, with no use. I tried to figure out the common reasons (1) Using a memory location which is not allocated. (2) Using memory which is freed. (3) Function use before declaration. I didn't use any other debuggers or tools other than ddd. My...
3
11442
by: Zheng Da | last post by:
Program received signal SIGSEGV, Segmentation fault. 0x40093343 in _int_malloc () from /lib/tls/libc.so.6 (gdb) bt #0 0x40093343 in _int_malloc () from /lib/tls/libc.so.6 #1 0x40094c54 in malloc () from /lib/tls/libc.so.6 It's really strange; I just call malloc() like "tmp=malloc(size);" the system gives me Segmentation fault I want to write a code to do like a dynamic array, and the code is as
6
4778
by: I_have_nothing | last post by:
Hi! I am new in C. I try to use dynamical allocation fuction malloc( ) and realloc( ). I found something strange. After several calling realloc( ), the malloc( ) will give me a Segmentation fault. If I just call realloc( ) once before calling malloc( ), it is OK. Why? I am trying to read some double-typed items from infile and save them
59
2910
by: Christian Christmann | last post by:
Hi, I'm wondering why this program does not crash with a segmentation fault: #include <malloc.h> #include <string.h> #include <stdio.h> int main()
6
5043
by: DanielJohnson | last post by:
int main() { printf("\n Hello World"); main; return 0; } This program terminate just after one loop while the second program goes on infinitely untill segmentation fault (core dumped) on gcc. The only difference is that in first I only call "main" and in second call
23
1709
by: sam_cit | last post by:
Hi Everyone, I have the following program unit, #include <stdlib.h> int main() { char *p = (char*)malloc(100); if(p==NULL)
36
1947
by: Ajay | last post by:
Hi All, I got a segmentation fault while accessing a structure element. I pasted the output from gdb and the backtrace. However if I am able successfully access the structure using the address from the gdb output after it seg faulted. Output from gdb also give below. Any idea y this is happening?
0
9386
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10144
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
9937
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9822
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8821
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6642
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5270
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5405
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
3
3522
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.