Convert jobs list to std::list

This commit is contained in:
ridiculousfish 2012-01-29 16:36:21 -08:00
parent 1a5d866a91
commit f243cd86c9
6 changed files with 123 additions and 97 deletions

View file

@ -2906,25 +2906,7 @@ static int builtin_source( parser_t &parser, wchar_t ** argv )
*/ */
static void make_first( job_t *j ) static void make_first( job_t *j )
{ {
job_t *prev=0; job_promote(j);
job_t *curr;
for( curr = first_job; curr != j; curr = curr->next )
{
prev=curr;
}
if( curr == j )
{
if( prev == 0 )
{
return;
}
else
{
prev->next = curr->next;
curr->next = first_job;
first_job = curr;
}
}
} }
@ -2933,7 +2915,7 @@ static void make_first( job_t *j )
*/ */
static int builtin_fg( parser_t &parser, wchar_t **argv ) static int builtin_fg( parser_t &parser, wchar_t **argv )
{ {
job_t *j=0; job_t *j=NULL;
if( argv[1] == 0 ) if( argv[1] == 0 )
{ {
@ -2941,7 +2923,9 @@ static int builtin_fg( parser_t &parser, wchar_t **argv )
Select last constructed job (I.e. first job in the job que) Select last constructed job (I.e. first job in the job que)
that is possible to put in the foreground that is possible to put in the foreground
*/ */
for( j=first_job; j; j=j->next )
job_iterator_t jobs;
while ((j = jobs.next()))
{ {
if( job_get_flag( j, JOB_CONSTRUCTED ) && (!job_is_completed(j)) && if( job_get_flag( j, JOB_CONSTRUCTED ) && (!job_is_completed(j)) &&
( (job_is_stopped(j) || (!job_get_flag(j, JOB_FOREGROUND)) ) && job_get_flag( j, JOB_CONTROL) ) ) ( (job_is_stopped(j) || (!job_get_flag(j, JOB_FOREGROUND)) ) && job_get_flag( j, JOB_CONTROL) ) )
@ -3121,8 +3105,9 @@ static int builtin_bg( parser_t &parser, wchar_t **argv )
if( argv[1] == 0 ) if( argv[1] == 0 )
{ {
job_t *j; job_t *j;
for( j=first_job; j; j=j->next ) job_iterator_t jobs;
{ while ((j = jobs.next()))
{
if( job_is_stopped(j) && job_get_flag( j, JOB_CONTROL ) && (!job_is_completed(j)) ) if( job_is_stopped(j) && job_get_flag( j, JOB_CONTROL ) && (!job_is_completed(j)) )
{ {
break; break;

View file

@ -271,8 +271,11 @@ static int builtin_jobs( parser_t &parser, wchar_t **argv )
/* /*
Ignore unconstructed jobs, i.e. ourself. Ignore unconstructed jobs, i.e. ourself.
*/ */
for( j=first_job; j; j=j->next ) job_iterator_t jobs;
job_t *j;
while ((j = jobs.next()))
{ {
if( (j->flags & JOB_CONSTRUCTED) && !job_is_completed(j) ) if( (j->flags & JOB_CONSTRUCTED) && !job_is_completed(j) )
{ {
builtin_jobs_print( j, mode, !found ); builtin_jobs_print( j, mode, !found );
@ -322,8 +325,10 @@ static int builtin_jobs( parser_t &parser, wchar_t **argv )
} }
else else
{ {
for( j= first_job; j; j=j->next ) job_iterator_t jobs;
{ job_t *j;
while ((j = jobs.next()))
{
/* /*
Ignore unconstructed jobs, i.e. ourself. Ignore unconstructed jobs, i.e. ourself.
*/ */

View file

@ -397,7 +397,8 @@ static int find_process( const wchar_t *proc,
if( flags & ACCEPT_INCOMPLETE ) if( flags & ACCEPT_INCOMPLETE )
{ {
for( j=first_job; j != 0; j=j->next ) job_iterator_t jobs;
while ((j = jobs.next()))
{ {
wchar_t jid[16]; wchar_t jid[16];
if( j->command == 0 ) if( j->command == 0 )
@ -454,7 +455,8 @@ static int find_process( const wchar_t *proc,
if( found ) if( found )
return 1; return 1;
for( j=first_job; j != 0; j=j->next ) job_iterator_t jobs;
while ((j = jobs.next()))
{ {
int offset; int offset;
@ -487,7 +489,8 @@ static int find_process( const wchar_t *proc,
return 1; return 1;
} }
for( j=first_job; j; j=j->next ) jobs.reset();
while ((j = jobs.next()))
{ {
process_t *p; process_t *p;
if( j->command == 0 ) if( j->command == 0 )

111
proc.cpp
View file

@ -95,7 +95,12 @@ static int last_status=0;
*/ */
static sig_atomic_t got_signal=0; static sig_atomic_t got_signal=0;
job_t *first_job=0; static std::list<job_t *> s_job_list;
job_list_t &job_list(void) {
return s_job_list;
}
int is_interactive=-1; int is_interactive=-1;
int is_interactive_session=0; int is_interactive_session=0;
int is_subshell=0; int is_subshell=0;
@ -143,25 +148,26 @@ void proc_init()
*/ */
static int job_remove( job_t *j ) static int job_remove( job_t *j )
{ {
job_t *prev=0, *curr=first_job; job_list_t &jobs = job_list();
while( (curr != 0) && (curr != j) ) job_list_t::iterator iter = find(jobs.begin(), jobs.end(), j);
{ if (iter != jobs.end()) {
prev = curr; jobs.erase(iter);
curr = curr->next; return 1;
} } else {
if( j != curr )
{
debug( 1, _( L"Job inconsistency" ) ); debug( 1, _( L"Job inconsistency" ) );
sanity_lose(); sanity_lose();
return 0; return 0;
} }
}
if( prev == 0 )
first_job = j->next; void job_promote(job_t *job)
else {
prev->next = j->next; job_list_t &jobs = job_list();
return 1; job_list_t::iterator loc = find(jobs.begin(), jobs.end(), job);
assert(loc != jobs.end());
/* Move the job to the beginning */
jobs.splice(jobs.begin(), jobs, loc);
} }
@ -181,10 +187,12 @@ void proc_destroy()
event.arguments = NULL; event.arguments = NULL;
sb_destroy( &event_pid ); sb_destroy( &event_pid );
sb_destroy( &event_status ); sb_destroy( &event_status );
while( first_job ) job_list_t &jobs = job_list();
while( ! jobs.empty() )
{ {
debug( 2, L"freeing leaked job %ls", first_job->command ); job_t *job = jobs.front();
job_free( first_job ); debug( 2, L"freeing leaked job %ls", job->command );
job_free( job );
} }
} }
@ -206,10 +214,9 @@ job_t *job_create()
while( job_get( free_id ) != 0 ) while( job_get( free_id ) != 0 )
free_id++; free_id++;
res = (job_t *)halloc( 0, sizeof(job_t) ); res = (job_t *)halloc( 0, sizeof(job_t) );
res->next = first_job;
res->job_id = free_id; res->job_id = free_id;
first_job = res; job_list().push_front(res);
job_set_flag( res, job_set_flag( res,
JOB_CONTROL, JOB_CONTROL,
(job_control_mode==JOB_CONTROL_ALL) || (job_control_mode==JOB_CONTROL_ALL) ||
@ -223,30 +230,22 @@ job_t *job_create()
job_t *job_get( int id ) job_t *job_get( int id )
{ {
job_t *res = first_job; job_iterator_t jobs;
if( id <= 0 ) job_t *job;
{ while ((job = jobs.next())) {
return res; if( id <= 0 || job->job_id == id)
return job;
} }
return NULL;
while( res != 0 )
{
if( res->job_id == id )
return res;
res = res->next;
}
return 0;
} }
job_t *job_get_from_pid( int pid ) job_t *job_get_from_pid( int pid )
{ {
job_t *res = first_job; job_iterator_t jobs;
job_t *job;
while( res != 0 ) while ((job = jobs.next())) {
{ if( job->pgid == pid )
if( res->pgid == pid ) return job;
return res;
res = res->next;
} }
return 0; return 0;
} }
@ -399,7 +398,8 @@ static void handle_child_status( pid_t pid, int status )
write( 2, mess, strlen(mess )); write( 2, mess, strlen(mess ));
*/ */
for( j=first_job; j && !found_proc; j=j->next ) job_iterator_t jobs;
while ((j = jobs.next()))
{ {
process_t *prev=0; process_t *prev=0;
for( p=j->first_process; p; p=p->next ) for( p=j->first_process; p; p=p->next )
@ -546,7 +546,7 @@ void proc_fire_event( const wchar_t *msg, int type, pid_t pid, int status )
int job_reap( int interactive ) int job_reap( int interactive )
{ {
job_t *j, *jnext; job_t *jnext;
int found=0; int found=0;
static int locked = 0; static int locked = 0;
@ -559,11 +559,14 @@ int job_reap( int interactive )
*/ */
if( locked>1 ) if( locked>1 )
return 0; return 0;
for( j=first_job; j; j=jnext) job_iterator_t jobs;
{ jnext = jobs.next();
while (jnext)
{
job_t *j = jnext;
jnext = jobs.next();
process_t *p; process_t *p;
jnext = j->next;
/* /*
If we are reaping only jobs who do not need status messages If we are reaping only jobs who do not need status messages
@ -960,9 +963,7 @@ void job_continue (job_t *j, int cont)
/* /*
Put job first in the job list Put job first in the job list
*/ */
job_remove( j ); job_promote(j);
j->next = first_job;
first_job = j;
job_set_flag( j, JOB_NOTIFIED, 0 ); job_set_flag( j, JOB_NOTIFIED, 0 );
CHECK_BLOCK(); CHECK_BLOCK();
@ -1160,7 +1161,8 @@ void proc_sanity_check()
job_t *j; job_t *j;
job_t *fg_job=0; job_t *fg_job=0;
for( j = first_job; j ; j=j->next ) job_iterator_t jobs;
while ((j = jobs.next()))
{ {
process_t *p; process_t *p;
@ -1174,9 +1176,6 @@ void proc_sanity_check()
validate_pointer( j->first_process, validate_pointer( j->first_process,
_( L"Process list pointer" ), _( L"Process list pointer" ),
0 ); 0 );
validate_pointer( j->next,
_( L"Job list pointer" ),
1 );
/* /*
More than one foreground job? More than one foreground job?

50
proc.h
View file

@ -15,6 +15,7 @@
#include <signal.h> #include <signal.h>
#include <unistd.h> #include <unistd.h>
#include <sys/time.h> #include <sys/time.h>
#include <list>
#include "util.h" #include "util.h"
#include "io.h" #include "io.h"
@ -233,14 +234,15 @@ typedef struct process
A struct represeting a job. A job is basically a pipeline of one A struct represeting a job. A job is basically a pipeline of one
or more processes and a couple of flags. or more processes and a couple of flags.
*/ */
typedef struct job class job_t
{ {
public:
/** /**
The original command which led to the creation of this The original command which led to the creation of this
job. It is used for displaying messages about job status job. It is used for displaying messages about job status
on the terminal. on the terminal.
*/ */
const wchar_t *command; const wchar_t *command;
/** /**
A linked list of all the processes in this job. A linked list of all the processes in this job.
@ -276,15 +278,14 @@ typedef struct job
/** /**
A pointer to the next job in the job queue A pointer to the next job in the job queue
*/ */
struct job *next; //struct job *next;
/** /**
Bitset containing information about the job. A combination of the JOB_* constants. Bitset containing information about the job. A combination of the JOB_* constants.
*/ */
int flags; int flags;
} };
job_t;
/** /**
Whether we are running a subshell command Whether we are running a subshell command
@ -316,10 +317,35 @@ extern int is_login;
*/ */
extern int is_event; extern int is_event;
/**
Linked list of all living jobs /** List of all living jobs */
*/ typedef std::list<job_t *> job_list_t;
extern job_t *first_job; job_list_t &job_list(void);
/** A class to aid iteration over jobs list */
class job_iterator_t {
job_list_t::iterator current, end;
public:
void reset(void) {
job_list_t &jobs = job_list();
this->current = jobs.begin();
this->end = jobs.end();
}
job_t *next() {
job_t *job = NULL;
if (current != end) {
job = *current;
++current;
}
return job;
}
job_iterator_t() {
this->reset();
}
};
/** /**
Whether a universal variable barrier roundtrip has already been Whether a universal variable barrier roundtrip has already been
@ -377,6 +403,11 @@ int proc_get_last_status();
*/ */
void job_free( job_t* j ); void job_free( job_t* j );
/**
Promotes a job to the front of the job list.
*/
void job_promote(job_t *job);
/** /**
Create a new job. Job struct is allocated using halloc, so anything Create a new job. Job struct is allocated using halloc, so anything
that should be freed with the job can uset it as a halloc context that should be freed with the job can uset it as a halloc context
@ -390,6 +421,7 @@ job_t *job_create();
*/ */
job_t *job_get(int id); job_t *job_get(int id);
/** /**
Return the job with the specified pid. Return the job with the specified pid.
*/ */

View file

@ -2519,7 +2519,7 @@ static void reader_super_highlight_me_plenty( int match_highlight_pos, array_lis
int exit_status() int exit_status()
{ {
if( is_interactive ) if( is_interactive )
return first_job == 0 && data->end_loop; return job_list().empty() && data->end_loop;
else else
return end_loop; return end_loop;
} }
@ -2549,7 +2549,8 @@ static void handle_end_loop()
} }
} }
for( j=first_job; j; j=j->next ) job_iterator_t jobs;
while ((j = jobs.next()))
{ {
if( !job_is_completed(j) ) if( !job_is_completed(j) )
{ {
@ -2574,7 +2575,8 @@ static void handle_end_loop()
in interactive mode. If isatty returns false, it in interactive mode. If isatty returns false, it
means stdin must have been closed. means stdin must have been closed.
*/ */
for( j = first_job; j; j=j->next ) job_iterator_t jobs;
while ((j = jobs.next()))
{ {
if( ! job_is_completed( j ) ) if( ! job_is_completed( j ) )
{ {