Question: I am writing a program where i run in a while (1) loop which blocks on a select call. My program listens on a server socket to which multiple clients connect. I also connect to a different server socket. So, i act as both the client and the server. 

Its an event based design which only acts on events/messages it receives on its sockets. So far so good.

This design works and i have no problems with this so far.

My problem is that based on some message that i receive on a socket i call a function foo which runs in a for loop and does some work which takes up a LOT of time (say 40-50 secs). Now while i am doing this, i dont go back to the while (1) loop where i am blocked on the select call. During this period of 40-50 secs i dont act on any messages/events that i receive on the my other sockets.

Is there a way to break my foo function so that i process only some part of it and then go back to my while (1) loop, check the sockets, and if there is nothing there then continue processing the foo() function. My problem is that if there is nothing on the socket then socket call will be blocked and i will not be able to process foo().

I cannot use the time parameter in select as i already use that for some other functionality?

EDIT: Is this a normal design to get the main loop to run in a while (1) loop thats only blocked on a select call and does different things based on the messages that it recieves on the different sockets that it is connected to?

Answer: 
You should create a thread to run your function, while the `select` will keep waiting for events.

Without threads, it would be complicated to pause & resume a process but you can do it just as a computer does: reserve some space to store the context of your processing when you exit `foo`. On the next call, it shall check for data to process in the context.  

Also, maybe you should consider pushing sockets info into a pipe/queue of messages to be processed later.

About "time parameter" I guess you are talking about the `select` timeout. It can be used for different events but you have to work it out, i.e. compute the minimal timeout of all the events you are listening (and if you are in an infinite loop, you will have to re-compute it on each loop).
The best solution is to start a new thread (or even `fork` off a new process).

If you don't want to do that you can change your select to be non-blocking while you have work to do. You also need to call your select regularly.

```
int mySelectHandler(); // Returns false if SELECT would block

// Main loop
while (1) {
    mySelectHandler();   // Check for new connections and messages
}

int bigWork() {

    int prevStatus = <current select status, blocking or non-blocking>;
    setStatus(NONBLOCKING);

    for (<some condition)) {
       <do some work>
       while (mySelectHandler())  // Check for new connections and messages
           ;
    }
    setStatus(prevStatus);
}

```

There is a caveat with this approach: If there is a second call to bigWork() before the first call ends, then the first call will be delayed until the second call has been processed.