* Advance the state machine of a connection. */
| 3136 | * Advance the state machine of a connection. |
| 3137 | */ |
| 3138 | static void |
| 3139 | advanceConnectionState(TState *thread, CState *st, StatsData *agg) |
| 3140 | { |
| 3141 | |
| 3142 | /* |
| 3143 | * gettimeofday() isn't free, so we get the current timestamp lazily the |
| 3144 | * first time it's needed, and reuse the same value throughout this |
| 3145 | * function after that. This also ensures that e.g. the calculated |
| 3146 | * latency reported in the log file and in the totals are the same. Zero |
| 3147 | * means "not set yet". Reset "now" when we execute shell commands or |
| 3148 | * expressions, which might take a non-negligible amount of time, though. |
| 3149 | */ |
| 3150 | pg_time_usec_t now = 0; |
| 3151 | |
| 3152 | /* |
| 3153 | * Loop in the state machine, until we have to wait for a result from the |
| 3154 | * server or have to sleep for throttling or \sleep. |
| 3155 | * |
| 3156 | * Note: In the switch-statement below, 'break' will loop back here, |
| 3157 | * meaning "continue in the state machine". Return is used to return to |
| 3158 | * the caller, giving the thread the opportunity to advance another |
| 3159 | * client. |
| 3160 | */ |
| 3161 | for (;;) |
| 3162 | { |
| 3163 | Command *command; |
| 3164 | |
| 3165 | switch (st->state) |
| 3166 | { |
| 3167 | /* Select transaction (script) to run. */ |
| 3168 | case CSTATE_CHOOSE_SCRIPT: |
| 3169 | st->use_file = chooseScript(thread); |
| 3170 | Assert(conditional_stack_empty(st->cstack)); |
| 3171 | |
| 3172 | pg_log_debug("client %d executing script \"%s\"", |
| 3173 | st->id, sql_script[st->use_file].desc); |
| 3174 | |
| 3175 | /* |
| 3176 | * If time is over, we're done; otherwise, get ready to start |
| 3177 | * a new transaction, or to get throttled if that's requested. |
| 3178 | */ |
| 3179 | st->state = timer_exceeded ? CSTATE_FINISHED : |
| 3180 | throttle_delay > 0 ? CSTATE_PREPARE_THROTTLE : CSTATE_START_TX; |
| 3181 | break; |
| 3182 | |
| 3183 | /* Start new transaction (script) */ |
| 3184 | case CSTATE_START_TX: |
| 3185 | pg_time_now_lazy(&now); |
| 3186 | |
| 3187 | /* establish connection if needed, i.e. under --connect */ |
| 3188 | if (st->con == NULL) |
| 3189 | { |
| 3190 | pg_time_usec_t start = now; |
| 3191 | |
| 3192 | if ((st->con = doConnect()) == NULL) |
| 3193 | { |
| 3194 | pg_log_error("client %d aborted while establishing connection", st->id); |
| 3195 | st->state = CSTATE_ABORTED; |
no test coverage detected