• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nasa / trick / 25456501308

06 May 2026 07:29PM UTC coverage: 55.935% (-0.8%) from 56.7%
25456501308

Pull #2011

github

web-flow
Merge 7ad262960 into 7054e405e
Pull Request #2011: Single-file CI and code style adoption

14612 of 26123 relevant lines covered (55.94%)

462107.16 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/trick_source/sim_services/MonteCarlo/MonteCarlo_slave_process_run.cpp
1

2
#include <sys/stat.h>
3
#include <sys/wait.h>
4
#include <stdio.h>
5
#include <sstream>
6

7
#include "trick/MonteCarlo.hh"
8
#include "trick/command_line_protos.h"
9
#include "trick/input_processor_proto.h"
10
#include "trick/message_proto.h"
11
#include "trick/message_type.h"
12
#include "trick/tc_proto.h"
13

14
/** @par Detailed Design: */
15
int Trick::MonteCarlo::slave_process_run() {
×
16
    int size;
17
    /** <ul><li> Read the length of the incoming message. */
18
    if (tc_read(&connection_device, (char *)&size, (int)sizeof(size)) != (int)sizeof(size) || (size = ntohl(size)) < 0) {
×
19
        if (verbosity >= MC_ERROR) {
×
20
            message_publish(MSG_ERROR, "Monte [%s:%d] Lost connection to Master while receiving new run.\nShutting down.\n",
×
21
                            machine_name.c_str(), slave_id) ;
22
        }
23
        slave_shutdown();
×
24
    }
25
    char *input = new char[size + 1];
×
26
    /** <li> Read the incoming message. */
27
    if (tc_read(&connection_device, input, size) != size) {
×
28
        if (verbosity >= MC_ERROR) {
×
29
            message_publish(MSG_ERROR, "Monte [%s:%d] Lost connection to Master while receiving new run.\nShutting down.\n",
×
30
                            machine_name.c_str(), slave_id) ;
31
        }
32
        slave_shutdown();
×
33
    }
34
    tc_disconnect(&connection_device);
×
35

36
    /**
37
     * <li> fork() a child process to execute the simulation.
38
     * This allows the slave to monitor the child and continue running
39
     * if it crashes or times out.
40
     */
41
    pid_t pid = fork();
×
42
    if (pid == -1) {
×
43
        if (verbosity >= MC_ERROR) {
×
44
            message_publish(MSG_ERROR, "Monte [%s:%d] Unable to fork new process for run.\nShutting down.\n",
×
45
                            machine_name.c_str(), slave_id) ;
46
        }
47
        slave_shutdown();
×
48
    /** <li>Parent process: */
49
    } else if (pid != 0) {
×
50
        int return_value = 0 ;
×
51
        /** <li> Wait for the child to finish. */
52
        if (waitpid(pid, &return_value, 0) == -1) {
×
53
            /* (Alex) On the Mac this check gives a lot of false positives.  I've commented out the code for now. */
54
            /*
55
            if (verbosity >= MC_ERROR) {
56
                message_publish(MSG_ERROR, "Monte [%s:%d] Error while waiting for run to finish.\nShutting down.\n",
57
                                machine_name.c_str(), slave_id) ;
58
            }
59
            slave_shutdown();
60
            */
61
        }
62

63
        if (WIFEXITED(return_value)) {
×
64
            // A successful sim sends its exit status to the master itself in
65
            // its shutdown job. Users can subvert this by calling exit, in
66
            // which case the master will eventually deem this run to have
67
            // timed out. But who would do that?!
68
            return 0;
×
69
        }
70

71
        int signal = WTERMSIG(return_value);
×
72
        /** <li> Extract the exit status of the child. */
73
        MonteRun::ExitStatus exit_status = signal == SIGALRM ? MonteRun::MC_RUN_TIMED_OUT : MonteRun::MC_RUN_DUMPED_CORE;
×
74
        if (verbosity >= MC_ERROR) {
×
75
            message_publish(MSG_ERROR, "Monte [%s:%d] Run killed by signal %d: %s\n",
×
76
                            machine_name.c_str(), slave_id, signal, strsignal(signal)) ;
77
        }
78
        connection_device.port = master_port;
×
79
        if (tc_connect(&connection_device) != TC_SUCCESS) {
×
80
            if (verbosity >= MC_ERROR) {
×
81
                message_publish(MSG_ERROR, "Monte [%s:%d] Lost connection to Master before results could be returned.\nShutting down.\n",
×
82
                                machine_name.c_str(), slave_id) ;
83
            }
84
            slave_shutdown();
×
85
        }
86
        if (verbosity >= MC_ALL) {
×
87
            message_publish(MSG_INFO, "Monte [%s:%d] Sending run exit status to master %d.\n",
×
88
                            machine_name.c_str(), slave_id, exit_status) ;
89
        }
90
        /** <li> Write the slaves id to the master. </ul> */
91
        int id = htonl(slave_id);
×
92
        tc_write(&connection_device, (char *)&id, (int)sizeof(id));
×
93
        /** <li> Write the child's exit status to the master. </ul> */
94
        return_value = htonl(exit_status);
×
95
        tc_write(&connection_device, (char *)&return_value, (int)sizeof(return_value));
×
96
        tc_disconnect(&connection_device);
×
97
        return 0;
×
98
    /** <li> Child process: */
99
    } else {
100
        input[size] = '\0';
×
101
        if ( ip_parse(input) != 0 ) {
×
102
            exit(MonteRun::MC_PROBLEM_PARSING_INPUT);
×
103
        }
104

105
        /** <ul><li> Create the run directory. */
106
        std::string output_dir = command_line_args_get_output_dir();
×
107
        if (access(output_dir.c_str(), F_OK) != 0) {
×
108
            if (mkdir(output_dir.c_str(), 0775) == -1) {
×
109
                exit(MonteRun::MC_CANT_CREATE_OUTPUT_DIR);
×
110
            }
111
        }
112

113
        std::stringstream ss_monte_input;
×
114
        ss_monte_input << output_dir << "/monte_input";
×
115
        FILE *fp = fopen(ss_monte_input.str().c_str(), "w");
×
116

117
        fprintf(fp,
×
118
          "# This run can be executed in stand alone (non-Monte Carlo) mode by running\n"
119
          "# the S_main executable with this file specified as the input file.\n\n");
120
        fprintf(fp, "if (sys.version_info > (3, 0)):\n");
×
121
        fprintf(fp, "    exec(open(\"%s\").read())\n", command_line_args_get_input_file());
×
122
        fprintf(fp, "else:\n");
×
123
        fprintf(fp, "    execfile(\"%s\")\n\n", command_line_args_get_input_file());
×
124
        fprintf(fp, "trick.mc_set_enabled(0)\n");
×
125
        fprintf(fp, "%s" , input);
×
126
        fclose(fp);
×
127
        delete [] input;
×
128

129
        /** <li> redirect stdout and stderr to files in the run directory */
130
        std::stringstream ss_stdout;
×
131
        ss_stdout << output_dir << "/stdout";
×
132
        freopen(ss_stdout.str().c_str(), "w", stdout);
×
133
        std::stringstream ss_stderr;
×
134
        ss_stderr << output_dir << "/stderr";
×
135
        freopen(ss_stderr.str().c_str(), "w", stderr);
×
136

137
        /** <li> Run the pre run jobs. */
138
        run_queue(&slave_pre_queue, "in slave_pre queue") ;
×
139

140
        /** <li> Set a timer to interrupt us after the timeout value. */
141
        struct sigaction default_alarm;
142
        default_alarm.sa_handler = SIG_DFL;
×
143
        sigaction(SIGALRM, &default_alarm, NULL);
×
144
        alarm((unsigned int)timeout);
×
145

146
        /**
147
         * <li> Return a non-zero result so the calling function (#slave)
148
         * will return, allowing the slave sim to complete.
149
         */
150
        return 1;
×
151
    }
×
152
    return 0;
×
153
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc