aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar ridiculousfish <corydoras@ridiculousfish.com>2012-01-29 16:36:21 -0800
committerGravatar ridiculousfish <corydoras@ridiculousfish.com>2012-01-29 16:36:21 -0800
commitf243cd86c98bf07cd2b22339f27e9fde5dad979f (patch)
tree439e6f293e0283ebf4ca3b5c437e0eede87e14c7
parent1a5d866a916ab0f7e0630c4205f3fff9b6375a3e (diff)
Convert jobs list to std::list
-rw-r--r--builtin.cpp31
-rw-r--r--builtin_jobs.cpp11
-rw-r--r--expand.cpp9
-rw-r--r--proc.cpp111
-rw-r--r--proc.h50
-rw-r--r--reader.cpp8
6 files changed, 123 insertions, 97 deletions
diff --git a/builtin.cpp b/builtin.cpp
index e2374f1d..5d27d654 100644
--- a/builtin.cpp
+++ b/builtin.cpp
@@ -2906,25 +2906,7 @@ static int builtin_source( parser_t &parser, wchar_t ** argv )
*/
static void make_first( job_t *j )
{
- job_t *prev=0;
- 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;
- }
- }
+ job_promote(j);
}
@@ -2933,7 +2915,7 @@ static void make_first( job_t *j )
*/
static int builtin_fg( parser_t &parser, wchar_t **argv )
{
- job_t *j=0;
+ job_t *j=NULL;
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)
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)) &&
( (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 )
{
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)) )
{
break;
diff --git a/builtin_jobs.cpp b/builtin_jobs.cpp
index 7d899599..229a7cbe 100644
--- a/builtin_jobs.cpp
+++ b/builtin_jobs.cpp
@@ -271,8 +271,11 @@ static int builtin_jobs( parser_t &parser, wchar_t **argv )
/*
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) )
{
builtin_jobs_print( j, mode, !found );
@@ -322,8 +325,10 @@ static int builtin_jobs( parser_t &parser, wchar_t **argv )
}
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.
*/
diff --git a/expand.cpp b/expand.cpp
index 7b347b5c..473f855a 100644
--- a/expand.cpp
+++ b/expand.cpp
@@ -397,7 +397,8 @@ static int find_process( const wchar_t *proc,
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];
if( j->command == 0 )
@@ -454,7 +455,8 @@ static int find_process( const wchar_t *proc,
if( found )
return 1;
- for( j=first_job; j != 0; j=j->next )
+ job_iterator_t jobs;
+ while ((j = jobs.next()))
{
int offset;
@@ -487,7 +489,8 @@ static int find_process( const wchar_t *proc,
return 1;
}
- for( j=first_job; j; j=j->next )
+ jobs.reset();
+ while ((j = jobs.next()))
{
process_t *p;
if( j->command == 0 )
diff --git a/proc.cpp b/proc.cpp
index b1dc85a5..25a6df03 100644
--- a/proc.cpp
+++ b/proc.cpp
@@ -95,7 +95,12 @@ static int last_status=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_session=0;
int is_subshell=0;
@@ -143,25 +148,26 @@ void proc_init()
*/
static int job_remove( job_t *j )
{
- job_t *prev=0, *curr=first_job;
- while( (curr != 0) && (curr != j) )
- {
- prev = curr;
- curr = curr->next;
- }
-
- if( j != curr )
- {
+ job_list_t &jobs = job_list();
+ job_list_t::iterator iter = find(jobs.begin(), jobs.end(), j);
+ if (iter != jobs.end()) {
+ jobs.erase(iter);
+ return 1;
+ } else {
debug( 1, _( L"Job inconsistency" ) );
sanity_lose();
- return 0;
- }
-
- if( prev == 0 )
- first_job = j->next;
- else
- prev->next = j->next;
- return 1;
+ return 0;
+ }
+}
+
+void job_promote(job_t *job)
+{
+ job_list_t &jobs = job_list();
+ 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;
sb_destroy( &event_pid );
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_free( first_job );
+ job_t *job = jobs.front();
+ 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 )
free_id++;
res = (job_t *)halloc( 0, sizeof(job_t) );
- res->next = first_job;
res->job_id = free_id;
- first_job = res;
-
+ job_list().push_front(res);
+
job_set_flag( res,
JOB_CONTROL,
(job_control_mode==JOB_CONTROL_ALL) ||
@@ -223,30 +230,22 @@ job_t *job_create()
job_t *job_get( int id )
{
- job_t *res = first_job;
- if( id <= 0 )
- {
- return res;
- }
-
- while( res != 0 )
- {
- if( res->job_id == id )
- return res;
- res = res->next;
+ job_iterator_t jobs;
+ job_t *job;
+ while ((job = jobs.next())) {
+ if( id <= 0 || job->job_id == id)
+ return job;
}
- return 0;
+ return NULL;
}
job_t *job_get_from_pid( int pid )
{
- job_t *res = first_job;
-
- while( res != 0 )
- {
- if( res->pgid == pid )
- return res;
- res = res->next;
+ job_iterator_t jobs;
+ job_t *job;
+ while ((job = jobs.next())) {
+ if( job->pgid == pid )
+ return job;
}
return 0;
}
@@ -399,7 +398,8 @@ static void handle_child_status( pid_t pid, int status )
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;
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 )
{
- job_t *j, *jnext;
+ job_t *jnext;
int found=0;
static int locked = 0;
@@ -559,11 +559,14 @@ int job_reap( int interactive )
*/
if( locked>1 )
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;
- jnext = j->next;
/*
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
*/
- job_remove( j );
- j->next = first_job;
- first_job = j;
+ job_promote(j);
job_set_flag( j, JOB_NOTIFIED, 0 );
CHECK_BLOCK();
@@ -1160,7 +1161,8 @@ void proc_sanity_check()
job_t *j;
job_t *fg_job=0;
- for( j = first_job; j ; j=j->next )
+ job_iterator_t jobs;
+ while ((j = jobs.next()))
{
process_t *p;
@@ -1174,9 +1176,6 @@ void proc_sanity_check()
validate_pointer( j->first_process,
_( L"Process list pointer" ),
0 );
- validate_pointer( j->next,
- _( L"Job list pointer" ),
- 1 );
/*
More than one foreground job?
diff --git a/proc.h b/proc.h
index 46fb3ea7..e04267b9 100644
--- a/proc.h
+++ b/proc.h
@@ -15,6 +15,7 @@
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
+#include <list>
#include "util.h"
#include "io.h"
@@ -233,14 +234,15 @@ typedef struct process
A struct represeting a job. A job is basically a pipeline of one
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
job. It is used for displaying messages about job status
on the terminal.
*/
- const wchar_t *command;
+ const wchar_t *command;
/**
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
*/
- struct job *next;
+ //struct job *next;
/**
Bitset containing information about the job. A combination of the JOB_* constants.
*/
int flags;
-}
- job_t;
+};
/**
Whether we are running a subshell command
@@ -316,10 +317,35 @@ extern int is_login;
*/
extern int is_event;
-/**
- Linked list of all living jobs
-*/
-extern job_t *first_job;
+
+/** List of all living jobs */
+typedef std::list<job_t *> job_list_t;
+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
@@ -378,6 +404,11 @@ int proc_get_last_status();
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
that should be freed with the job can uset it as a halloc context
when allocating.
@@ -390,6 +421,7 @@ job_t *job_create();
*/
job_t *job_get(int id);
+
/**
Return the job with the specified pid.
*/
diff --git a/reader.cpp b/reader.cpp
index 0381eae9..a04fb9ac 100644
--- a/reader.cpp
+++ b/reader.cpp
@@ -2519,7 +2519,7 @@ static void reader_super_highlight_me_plenty( int match_highlight_pos, array_lis
int exit_status()
{
if( is_interactive )
- return first_job == 0 && data->end_loop;
+ return job_list().empty() && data->end_loop;
else
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) )
{
@@ -2574,7 +2575,8 @@ static void handle_end_loop()
in interactive mode. If isatty returns false, it
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 ) )
{