dict_base::dict_base(object_cref data) : object(call(data)) {}
inline Real background_create_gradient(Real w, Real h, Real col1, Real col2, Real kind) { return call(functions[736], w, h, col1, col2, kind); }
function( void ( *fn )( argument_types ... ) ) { m_fn = [ this, fn ]( const std::vector< argument > &args ){ call( fn, args ); }; m_argument_types = { type_id< argument_types >()... }; }
inline void background_replace(Real ind, String fname, Real removeback, Real smooth) { call(functions[732], ind, fname, removeback, smooth); }
inline void background_replace_background(Real ind, String fname) { call(functions[734], ind, fname); }
inline void background_save(Real ind, String fname) { call(functions[728], ind, fname); }
inline void background_assign(Real ind, Real back) { call(functions[730], ind, back); }
bool DBDirectClient::callRead(Message& toSend, Message& response) { return call(toSend, response); }
static bool call(I1 const& a, I2 const& b, mpl::false_) { return *a > *b || (!(*b > *a) && call(fusion::next(a), fusion::next(b))); }
template<void (CPUcore::*op)()> void CPUcore::op_read_const_w() { rd.l = op_readpc(); L rd.h = op_readpc(); call(op); }
/* * EXEC 命令的实现 */ void execCommand(redisClient *c) { int j; // 用于保存执行命令、命令的参数和参数数量的副本 robj **orig_argv; int orig_argc; struct redisCommand *orig_cmd; // 只能在 MULTI 已启用的情况下执行 if (!(c->flags & REDIS_MULTI)) { addReplyError(c,"EXEC without MULTI"); return; } /* Check if we need to abort the EXEC because: * 以下情况发生时,取消事务 * * 1) Some WATCHed key was touched. * 某些被监视的键已被修改(状态为 REDIS_DIRTY_CAS) * * 2) There was a previous error while queueing commands. * 有命令在入队时发生错误(状态为 REDIS_DIRTY_EXEC) * * A failed EXEC in the first case returns a multi bulk nil object * (technically it is not an error but a special behavior), while * in the second an EXECABORT error is returned. * * 第一种情况返回多个空白 NULL 对象, * 第二种情况返回一个 EXECABORT 错误。 */ if (c->flags & (REDIS_DIRTY_CAS|REDIS_DIRTY_EXEC)) { // 根据状态,决定返回的错误的类型 addReply(c, c->flags & REDIS_DIRTY_EXEC ? shared.execaborterr : shared.nullmultibulk); // 以下四句可以用 discardTransaction() 来替换 freeClientMultiState(c); initClientMultiState(c); c->flags &= ~(REDIS_MULTI|REDIS_DIRTY_CAS|REDIS_DIRTY_EXEC); unwatchAllKeys(c); goto handle_monitor; } /* Replicate a MULTI request now that we are sure the block is executed. * This way we'll deliver the MULTI/..../EXEC block as a whole and * both the AOF and the replication link will have the same consistency * and atomicity guarantees. */ // 向所有附属节点和 AOF 文件发送 MULTI 命令 execCommandReplicateMulti(c); /* Exec all the queued commands */ unwatchAllKeys(c); /* Unwatch ASAP otherwise we'll waste CPU cycles */ // 将三个原始参数备份起来 orig_argv = c->argv; orig_argc = c->argc; orig_cmd = c->cmd; addReplyMultiBulkLen(c,c->mstate.count); // 执行所有入队的命令 for (j = 0; j < c->mstate.count; j++) { // 因为 call 可能修改命令,而命令需要传送给其他同步节点 // 所以这里将要执行的命令(及其参数)先备份起来 c->argc = c->mstate.commands[j].argc; c->argv = c->mstate.commands[j].argv; c->cmd = c->mstate.commands[j].cmd; // 执行命令 call(c,REDIS_CALL_FULL); /* Commands may alter argc/argv, restore mstate. */ // 还原原始的参数到队列里 c->mstate.commands[j].argc = c->argc; c->mstate.commands[j].argv = c->argv; c->mstate.commands[j].cmd = c->cmd; } // 还原三个原始命令 c->argv = orig_argv; c->argc = orig_argc; c->cmd = orig_cmd; // 以下三句也可以用 discardTransaction() 来替换 freeClientMultiState(c); initClientMultiState(c); c->flags &= ~(REDIS_MULTI|REDIS_DIRTY_CAS|REDIS_DIRTY_EXEC); /* Make sure the EXEC command is always replicated / AOF, since we * always send the MULTI command (we can't know beforehand if the * next operations will contain at least a modification to the DB). */ server.dirty++; handle_monitor: /* Send EXEC to clients waiting data from MONITOR. We do it here * since the natural order of commands execution is actually: * MUTLI, EXEC, ... commands inside transaction ... * Instead EXEC is flagged as REDIS_CMD_SKIP_MONITOR in the command * table, and we do it here with correct ordering. */ // 向同步节点发送命令 if (listLength(server.monitors) && !server.loading) replicationFeedMonitors(c,server.monitors,c->db->id,c->argv,c->argc); }
template<void (CPUcore::*op)()> void CPUcore::op_read_sr_b() { sp = op_readpc(); op_io(); L rd.l = op_readsp(sp); call(op); }
template<void (CPUcore::*op)()> void CPUcore::op_read_addr_b() { aa.l = op_readpc(); aa.h = op_readpc(); L rd.l = op_readdbr(aa.w); call(op); }
template<void (CPUcore::*op)()> void CPUcore::op_read_dp_b() { dp = op_readpc(); op_io_cond2(); L rd.l = op_readdp(dp); call(op); }
inline Real background_get_width(Real ind) { return call(functions[726], ind); }
static bool call(I1 const& a, I2 const& b) { typename result_of::equal_to<I1, end1_type>::type eq; return call(a, b, eq); }
inline Real background_get_height(Real ind) { return call(functions[727], ind); }
Object* BlockEnvironment::call_prim(STATE, CallFrame* call_frame, Executable* exec, Module* mod, Arguments& args) { return call(state, call_frame, args); }
inline Real background_duplicate(Real ind) { return call(functions[729], ind); }
inline Real background_create_from_surface(Real id, Real x, Real y, Real w, Real h, Real removeback, Real smooth) { return call(functions[738], id, x, y, w, h, removeback, smooth); }
inline Real background_add(String fname, Real removeback, Real smooth) { return call(functions[731], fname, removeback, smooth); }
inline void background_delete(Real ind) { call(functions[739], ind); }
inline Real background_add_background(String fname) { return call(functions[733], fname); }
inline void background_set_alpha_from_background(Real ind, Real back) { call(functions[740], ind, back); }
inline Real background_create_color(Real w, Real h, Real col) { return call(functions[735], w, h, col); }
///@{ inline Real background_exists(Real ind) { return call(functions[724], ind); }
inline Real background_create_from_screen(Real x, Real y, Real w, Real h, Real removeback, Real smooth) { return call(functions[737], x, y, w, h, removeback, smooth); }
inline String background_get_name(Real ind) { return call(functions[725], ind); }
int main(int argc, char *args[]) { if(argc <= 1) { /* * Comprobamos que al menos se pasó un parámetro de consola. * De ser así, intentamos leer el primero como el número de procesos * participantes en el problema del consenso. Si no, chilla */ fprintf(stderr, "At least, there must be one numeric parameter to be used as contenders number\n"); exit(EXIT_FAILURE); }//comprueba el número de argumentos unsigned int procnum = atoi(args[1]); if(procnum <= 1) { fprintf(stderr, "At least, two processes must be created. Use as parameter any number grather than 1"); exit(EXIT_FAILURE); }//si se pidio crear menos de 2 hijos, chilla /* * vea la descripción de stop_handler para más información de la siguente * linea. SIGINT es la señal que le envía el sistema a la aplicación cuando * el usuario hace explícito que quiere interrumpirla (por ejemplo, dando * ctrl +c) */ signal(SIGINT, stop_handler); // hay que declarar las variables compartidas como tales decision = mmap(NULL, sizeof(*decision), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); // notemos que tenemos apuntadores a las variables compartidas *decision = 0; mutex = sem_open(MUTEX, O_CREAT, 0644, 1); x = mmap(NULL, sizeof(*x), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); *x = 0; y = mmap(NULL, sizeof(*y), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); *y = 0; finish = mmap(NULL, sizeof(*finish), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); *finish = 0; unsigned int failures = 0; pid_t cpid; for(; i < procnum; i++) { if((cpid = fork()) < 0) { failures++; fprintf(stderr, "Houston, we had a problem when creating %u of %u child processes\n", failures, procnum); } else if(cpid == 0) { i -= failures; // aseguramos conteo continuo i++;// note que estas 2 instrcciones no altera el i del padre srand(time(NULL)); // new Random mutex = sem_open(MUTEX, 0); // recuperamos el semáforo aux = rand(); call(aux %2); // call contiene un exit, este termina el proceso }//actúa de acuerdo en dónde siga: padre, hijo o error santo }//pone a competir a tantos procesos hijos como haya sido indicado /* * La combinación de todos los exit en los call de los hijos y los * waitpid, son nuestro Future en C. Vamos a esperar en un ciclo, que no es * una espera ocupada, recordemos que waitpid se encarga de bloquear * eficientemente el proceso padre. El ciclo nos sirve para comprobar que * no hay ningún proceso hijo restante */ while(cpid = waitpid(-1, NULL, 0)) { if(errno == ECHILD) { break; }// si en efecto no hay más hijos o si un hijo murio anormalmente }//esperamos a un evento que reanude al padre fprintf(stdout, "Process decided %u\n", *decision); //liberamos la memoria usada por las variables compartidas munmap(decision, sizeof(*decision)); sem_unlink(MUTEX); munmap(x, sizeof(*x)); munmap(y, sizeof(*y)); munmap(finish, sizeof(*finish)); return 0; }//main
// ECMA 8.6.2.2 void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) { ASSERT(value); ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); if (propertyName == exec->propertyNames().underscoreProto) { // Setting __proto__ to a non-object, non-null value is silently ignored to match Mozilla. if (!value.isObject() && !value.isNull()) return; JSValue nextPrototypeValue = value; while (nextPrototypeValue && nextPrototypeValue.isObject()) { JSObject* nextPrototype = asObject(nextPrototypeValue)->unwrappedObject(); if (nextPrototype == this) { throwError(exec, GeneralError, "cyclic __proto__ value"); return; } nextPrototypeValue = nextPrototype->prototype(); } setPrototype(value); return; } // Check if there are any setters or getters in the prototype chain JSValue prototype; for (JSObject* obj = this; !obj->structure()->hasGetterSetterProperties(); obj = asObject(prototype)) { prototype = obj->prototype(); if (prototype.isNull()) { putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot); return; } } unsigned attributes; JSCell* specificValue; if ((m_structure->get(propertyName, attributes, specificValue) != WTF::notFound) && attributes & ReadOnly) return; for (JSObject* obj = this; ; obj = asObject(prototype)) { if (JSValue gs = obj->getDirect(propertyName)) { if (gs.isGetterSetter()) { JSObject* setterFunc = asGetterSetter(gs)->setter(); if (!setterFunc) { throwSetterError(exec); return; } CallData callData; CallType callType = setterFunc->getCallData(callData); MarkedArgumentBuffer args; args.append(value); call(exec, setterFunc, callType, callData, this, args); return; } // If there's an existing property on the object or one of its // prototypes it should be replaced, so break here. break; } prototype = obj->prototype(); if (prototype.isNull()) break; } putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot); return; }