OP * clone_op(pTHX_ const OP * const o, const unsigned int paramcount) { OP * clone = NULL; if (o->op_type == OP_LEAVESUB) return clone_op(cUNOPo->op_first, paramcount); else if (o->op_flags & OPf_KIDS) { OP *kid = cUNOPo->op_first; OP *first = NULL; OP *last = NULL; do { OP * child = clone_op(kid, paramcount); if (!child) continue; clone = op_append_elem(o->op_type, clone, child); } while (kid = kid->op_sibling); return clone; } else switch (o->op_type) { case OP_CONST: return newSVOP(o->op_type, 0, cSVOPo_sv); case OP_PUSHMARK: return newOP(o->op_type, 0); case OP_NEXTSTATE: return newSTATEOP((U8)o->op_flags, NULL, NULL); case OP_NULL: return NULL; default: croak("Unsupported op type: %s", PL_op_name[o->op_type]); } }
void *bank_server(void *args) { OpQueue queue; init_opqueue(&queue); int balance = 0; int locked_by = -1; while(1) { Operation *op = NULL; if(operation.status == 1) { pthread_mutex_lock(&operation.mutex); op = clone_op(&operation); operation.status = 0; pthread_mutex_unlock(&operation.mutex); fprintf(stderr, "[Thread %d], operation %s, new op", op->client_id, code_to_text(op->code)); } else if(locked_by == -1) { op = pop_op(&queue); if(op != NULL) { fprintf(stderr, "[Thread %d], operation %s, popped op", op->client_id, code_to_text(op->code)); } } else { continue; } if(op == NULL) { continue; } int is_performable = can_perform_op(op->code, op->client_id, locked_by); if(is_performable != 0) { pthread_mutex_lock(&op->put_answer_to->mutex); if(is_performable == 1) { switch(op->code) { case OP_LOOK: op->put_answer_to->comment = ""; break; case OP_LOCK: op->put_answer_to->comment = "successfully locked"; locked_by = op->client_id; break; case OP_UNLOCK: op->put_answer_to->comment = "successfully unlocked"; locked_by = -1; break; case OP_INC: balance += op->value; op->put_answer_to->comment = "successfuly added"; break; case OP_DEC: balance -= op->value; op->put_answer_to->comment = "successfully withdrawed"; break; } fprintf(stderr, " - completed\n"); } else { op->put_answer_to->comment = "balance not locked"; fprintf(stderr, " - declined\n"); } op->put_answer_to->status = is_performable; op->put_answer_to->value = balance; // free(op); pthread_cond_signal(&op->put_answer_to->cond); pthread_mutex_unlock(&op->put_answer_to->mutex); } else { push_op(&queue, op); fprintf(stderr, " - pushed to queue\n"); } } return NULL; }