void *acceptJob(void * param) {
	pthread_mutex_lock(&McantJobs);
	cantJobs++;
	pthread_mutex_unlock(&McantJobs);
	int *socketAcceptedPtr = (int *) param;
	int jobSocket = *socketAcceptedPtr;
	free(socketAcceptedPtr);

	t_job *job = desserializeJob(jobSocket, cantJobs);
	job->socket = jobSocket;

	if (job->combiner)
		log_info(logger, "|JOB %d| Begin (Combiner)------------", job->id);
	else
		log_info(logger, "|JOB %d| Begin (No Combiner)---------", job->id);

	planMaps(job);

	if (job->combiner) {
		combinerReducePlanning(job);
	} else
		noCombinerReducePlanning(job);
	log_info(logger, "|JOB %d| Finished -------------------", job->id);
	sendDieOrder(job->socket, COMMAND_RESULT_OK);
	freeJob(job);
	return NULL;
}
示例#2
0
void Exec()
{
    if(strcmp(CmdBuf[CmdNum-1].args[0],"bg")==0)
         bg();
    else if(strcmp(CmdBuf[CmdNum-1].args[0],"fg")==0)
         fg();
    else if(strcmp(CmdBuf[CmdNum-1].args[0],"cd")==0)
    {
        if(chdir(CmdBuf[CmdNum-1].args[1])<0)
             printf("目录不正确!!\n");
    }
    else if(strcmp(CmdBuf[CmdNum-1].args[0],"history")==0)
         ListHis();
    else if(strcmp(CmdBuf[CmdNum-1].args[0],"jobs")==0)
         ListJob();
    else if(strcmp(CmdBuf[CmdNum-1].args[0],"exit")==0)
    {
        DelHis();
        freeJob();
        exit(0);
    }
    else if(strcmp(CmdBuf[CmdNum-1].args[0],"rm")==0)
        beforeRemove(CmdBuf[CmdNum-1].args[1]);
    else
         ExecOut();
}
示例#3
0
void notificarMap(t_job *job, t_map *map) {
	log_info(logger, "|JOB %d| Planned Map: %d on Node: %s (Block:%d)", job->id, map->id, map->nodeName, map->numBlock);
	map->done = false;
	if (0 > serializeMapToOrder(job->socket, map)) {
		log_error(logger, "|JOB %d| Died when sending map order", job->id);
		freeJob(job);
		pthread_exit(NULL);
	}
}
示例#4
0
文件: ack.c 项目: lamby/pkg-disque
/* Try to garbage collect the job. */
void tryJobGC(job *job) {
    if (job->state != JOB_STATE_ACKED) return;

    int dummy_ack = dictSize(job->nodes_delivered) == 0;
    serverLog(LL_VERBOSE,"GC %.42s", job->id);

    /* Don't overflow the count, it's only useful for the exponential delay.
     * Actually we'll keep trying forever. */
    if (job->gc_retry != JOB_GC_RETRY_COUNT_MAX) job->gc_retry++;

    /* nodes_confirmed is used in order to store all the nodes that have the
     * job in ACKed state, so that the job can be evicted when we are
     * confident the job will not be reissued. */
    if (job->nodes_confirmed == NULL) {
        job->nodes_confirmed = dictCreate(&clusterNodesDictType,NULL);
        dictAdd(job->nodes_confirmed,myself->name,myself);
    }

    /* Check ASAP if we already reached all the nodes. This special case
     * here is mainly useful when the job replication factor is 1, so
     * there is no SETACK to send, nor GOTCAK to receive.
     *
     * Also check if this is a dummy ACK but the cluster size is now 1:
     * in such a case we don't have other nodes to send SETACK to, we can
     * just remove the ACK. Note that dummy ACKs are not created at all
     * if the cluster size is 1, but this code path may be entered as a result
     * of the cluster getting resized to a single node. */
    int all_nodes_reached =
        (!dummy_ack) &&
        (dictSize(job->nodes_delivered) == dictSize(job->nodes_confirmed));
    int dummy_ack_single_node = dummy_ack && server.cluster->size == 1;

    if (all_nodes_reached || dummy_ack_single_node) {
        serverLog(LL_VERBOSE,
            "Deleting %.48s: all nodes reached in tryJobGC()",
            job->id);
        unregisterJob(job);
        freeJob(job);
        return;
    }

    /* Send a SETACK message to all the nodes that may have a message but are
     * still not listed in the nodes_confirmed hash table. However if this
     * is a dummy ACK (created by ACKJOB command acknowledging a job we don't
     * know) we have to broadcast the SETACK to everybody in search of the
     * owner. */
    dict *targets = dictSize(job->nodes_delivered) == 0 ?
                    server.cluster->nodes : job->nodes_delivered;
    dictForeach(targets,de)
        clusterNode *node = dictGetVal(de);
        if (dictFind(job->nodes_confirmed,node->name) == NULL)
            clusterSendSetAck(node,job);
    dictEndForeach
}
示例#5
0
void removeJob(struct jobSet * jobList, struct job * job) {
    struct job * prevJob;

    freeJob(job); 
    if (job == jobList->head) {
        jobList->head = job->next;
    } else {
        prevJob = jobList->head;
        while (prevJob->next != job) prevJob = prevJob->next;
        prevJob->next = job->next;
    }

    free(job);
}
示例#6
0
文件: ack.c 项目: lamby/pkg-disque
/* FASTACK jobid_1 jobid_2 ... jobid_N
 *
 * Performs a fast acknowledge of the specified jobs.
 * A fast acknowledge does not really attempt to make sure all the nodes
 * that may have a copy recive the ack. The job is just discarded and
 * a best-effort DELJOB is sent to all the nodes that may have a copy
 * without caring if they receive or not the message.
 *
 * This command will more likely result in duplicated messages delivery
 * during network partiitons, but uses less messages compared to ACKJOB.
 *
 * If a job is not known, a cluster-wide DELJOB is broadcasted.
 *
 * The command returns the number of jobs that are deleted from the local
 * node as a result of receiving the command.
 */
void fastackCommand(client *c) {
    int j, known = 0;

    if (validateJobIDs(c,c->argv+1,c->argc-1) == C_ERR) return;

    /* Perform the appropriate action for each job. */
    for (j = 1; j < c->argc; j++) {
        job *job = lookupJob(c->argv[j]->ptr);
        if (job == NULL) {
            /* Job not known, just broadcast the DELJOB message to everybody. */
            clusterBroadcastJobIDMessage(server.cluster->nodes,c->argv[j]->ptr,
                                         CLUSTERMSG_TYPE_DELJOB,0,
                                         CLUSTERMSG_NOFLAGS);
        } else {
            clusterBroadcastDelJob(job);
            unregisterJob(job);
            freeJob(job);
            known++;
        }
    }
    addReplyLongLong(c,known);
}
char *recvResult(t_job *job) {
	void *buffer;
	char *nodeID = NULL;
	size_t sbuffer = 0;
	if (0 > socket_recv_packet(job->socket, &buffer, &sbuffer)) {
		log_error(logger, "|JOB %d| Died when reciving results", job->id);
		freeJob(job);
		pthread_exit(NULL);
		return NULL;
	}

	uint8_t resultFrom;
	memcpy(&resultFrom, buffer, sizeof(resultFrom));
	switch (resultFrom) {
	case COMMAND_MAP:
		desserializeMapResult(buffer, sizeof(resultFrom), job);
		break;
	case COMMAND_REDUCE:
		nodeID = desserializaReduceResult(buffer, sizeof(resultFrom), job);
		break;
	}
	return nodeID;
}
示例#8
0
/* Return cmd->numProgs as 0 if no command is present (e.g. an empty
   line). If a valid command is found, commandPtr is set to point to
   the beginning of the next command (if the original command had 
   more than one job associated with it) or NULL if no more 
   commands are present. */
int parseCommand(char ** commandPtr, struct job * job, int * isBg) {
    char * command;
    char * returnCommand = NULL;
    char * src, * buf;
    int argc = 0;
    int done = 0;
    int argvAlloced;
    char quote = '\0';  
    int count;
    struct childProgram * prog;

    /* skip leading white space */
    while (**commandPtr && isspace(**commandPtr)) (*commandPtr)++;

    /* this handles empty lines and leading '#' characters */
        if (!**commandPtr || (**commandPtr=='#')) {
        job->numProgs = 0;
        *commandPtr = NULL;
        return 0;
    }

    *isBg = 0;
    job->numProgs = 1;
    job->progs = malloc(sizeof(*job->progs));

    /* We set the argv elements to point inside of this string. The 
       memory is freed by freeJob(). 

       Getting clean memory relieves us of the task of NULL 
       terminating things and makes the rest of this look a bit 
       cleaner (though it is, admittedly, a tad less efficient) */
    job->cmdBuf = command = calloc(1, strlen(*commandPtr) + 1);
    job->text = NULL;

    prog = job->progs;

    argvAlloced = 5;
    prog->argv = malloc(sizeof(*prog->argv) * argvAlloced);
    prog->argv[0] = job->cmdBuf;

    buf = command;
    src = *commandPtr;
    while (*src && !done) {
        if (quote == *src) {
            quote = '\0';
        } else if (quote) {
            if (*src == '\\') {
                src++;
                if (!*src) {
                    fprintf(stderr, 
			    "character expected after \\\n");
                    freeJob(job);
                    return 1;
                }

                /* in shell, "\'" should yield \' */
                if (*src != quote) *buf++ = '\\';
            }
            *buf++ = *src;
        } else if (isspace(*src)) {
            if (*prog->argv[argc]) {
                buf++, argc++;
                /* +1 here leaves room for the NULL which 
		   ends argv */
                if ((argc + 1) == argvAlloced) {
                    argvAlloced += 5;
                    prog->argv = realloc(prog->argv, 
				sizeof(*prog->argv) * argvAlloced);
                }
                prog->argv[argc] = buf;
            }
        } else switch (*src) {
        case '"':
        case '\'':
            quote = *src;
            break;

        case '#':                         /* comment */
            done = 1;
            break;

        case '&':                         /* background */
            *isBg = 1;
        case ';':                         /* multiple commands */
            done = 1;
            returnCommand = *commandPtr + (src - *commandPtr) + 1;
            break;

        case '\\':
            src++;
            if (!*src) {
                freeJob(job);
                fprintf(stderr, "character expected after \\\n");
                return 1;
            }
            /* fallthrough */
        default:
            *buf++ = *src;
        }

        src++;
    }

    if (*prog->argv[argc]) {
        argc++;
    }
    if (!argc) {
        freeJob(job);
        return 0;
    }
    prog->argv[argc] = NULL;

    if (!returnCommand) {
        job->text = malloc(strlen(*commandPtr) + 1);
        strcpy(job->text, *commandPtr);
    } else {
        /* This leaves any trailing spaces, which is a bit sloppy */

        count = returnCommand - *commandPtr;
        job->text = malloc(count + 1);
        strncpy(job->text, *commandPtr, count);
        job->text[count] = '\0';
    }

    *commandPtr = returnCommand;

    return 0;
}
CLicenseMgr::~CLicenseMgr()
{
	CheckInLicense(m_feature.c_str());
	freeJob();
}
示例#10
0
/**
* Deallocs the NodePtr and the JobPtr it contains
* @param node NodePtr to dealloc
*/
void freeNode (NodePtr node)
{
	if (isNodeNull(node)) return;
	freeJob(node->data);
	buddy_free(node);
}
示例#11
0
文件: ladsh4.c 项目: Cergoo/junk
/* Return cmd->numProgs as 0 if no command is present (e.g. an empty
   line). If a valid command is found, commandPtr is set to point to
   the beginning of the next command (if the original command had more 
   then one job associated with it) or NULL if no more commands are 
   present. */
int parseCommand(char ** commandPtr, struct job * job, int * isBg) {
    char * command;
    char * returnCommand = NULL;
    char * src, * buf, * chptr;
    int argc = 0;
    int done = 0;
    int argvAlloced;
    int i;
    char quote = '\0';  
    int count;
    struct childProgram * prog;

    /* skip leading white space */
    while (**commandPtr && isspace(**commandPtr)) (*commandPtr)++;

    /* this handles empty lines and leading '#' characters */
        if (!**commandPtr || (**commandPtr=='#')) {
        job->numProgs = 0;
        *commandPtr = NULL;
        return 0;
    }

    *isBg = 0;
    job->numProgs = 1;
    job->progs = malloc(sizeof(*job->progs));

    /* We set the argv elements to point inside of this string. The 
       memory is freed by freeJob(). 

       Getting clean memory relieves us of the task of NULL 
       terminating things and makes the rest of this look a bit 
       cleaner (though it is, admittedly, a tad less efficient) */
    job->cmdBuf = command = calloc(1, strlen(*commandPtr) + 1);
    job->text = NULL;

    prog = job->progs;
    prog->numRedirections = 0;
    prog->redirections = NULL;
    prog->freeGlob = 0;
    prog->isStopped = 0;

    argvAlloced = 5;
    prog->argv = malloc(sizeof(*prog->argv) * argvAlloced);
    prog->argv[0] = job->cmdBuf;

    buf = command;
    src = *commandPtr;
    while (*src && !done) {
        if (quote == *src) {
            quote = '\0';
        } else if (quote) {
            if (*src == '\\') {
                src++;
                if (!*src) {
                    fprintf(stderr, "character expected after \\\n");
                    freeJob(job);
                    return 1;
                }

                /* in shell, "\'" should yield \' */
                if (*src != quote) *buf++ = '\\';
            } else if (*src == '*' || *src == '?' || *src == '[' || 
                       *src == ']')
                *buf++ = '\\';
            *buf++ = *src;
        } else if (isspace(*src)) {
            if (*prog->argv[argc]) {
                buf++, argc++;
                /* +1 here leaves room for the NULL which ends argv */
                if ((argc + 1) == argvAlloced) {
                    argvAlloced += 5;
                    prog->argv = realloc(prog->argv, 
				    sizeof(*prog->argv) * argvAlloced);
                }
                prog->argv[argc] = buf;

                globLastArgument(prog, &argc, &argvAlloced);
            }
        } else switch (*src) {
          case '"':
          case '\'':
            quote = *src;
            break;

          case '#':                         /* comment */
            done = 1;
            break;

          case '>':                         /* redirections */
          case '<':
            i = prog->numRedirections++;
            prog->redirections = realloc(prog->redirections, 
                                sizeof(*prog->redirections) * (i + 1));

            prog->redirections[i].fd = -1;
            if (buf != prog->argv[argc]) {
                /* the stuff before this character may be the file number 
                   being redirected */
                prog->redirections[i].fd = strtol(prog->argv[argc], &chptr, 10);

                if (*chptr && *prog->argv[argc]) {
                    buf++, argc++;
                    globLastArgument(prog, &argc, &argvAlloced);
                }
            }

            if (prog->redirections[i].fd == -1) {
                if (*src == '>')
                    prog->redirections[i].fd = 1;
                else
                    prog->redirections[i].fd = 0;
            }

            if (*src++ == '>') {
                if (*src == '>')
                    prog->redirections[i].type = REDIRECT_APPEND, src++;
                else 
                    prog->redirections[i].type = REDIRECT_OVERWRITE;
            } else {
                prog->redirections[i].type = REDIRECT_INPUT;
            }

            /* This isn't POSIX sh compliant. Oh well. */
            chptr = src;
            while (isspace(*chptr)) chptr++;

            if (!*chptr) {
                fprintf(stderr, "file name expected after %c\n", *src);
                freeJob(job);
                return 1;
            }

            prog->redirections[i].filename = buf;
            while (*chptr && !isspace(*chptr)) 
                *buf++ = *chptr++;

            src = chptr - 1;                /* we src++ later */
            prog->argv[argc] = ++buf;
            break;

          case '|':                         /* pipe */
            /* finish this command */
            if (*prog->argv[argc]) argc++;
            if (!argc) {
                fprintf(stderr, "empty command in pipe\n");
                freeJob(job);
                return 1;
            }
            prog->argv[argc] = NULL;

            /* and start the next */
            job->numProgs++;
            job->progs = realloc(job->progs, 
                                 sizeof(*job->progs) * job->numProgs);
            prog = job->progs + (job->numProgs - 1);
            prog->numRedirections = 0;
            prog->redirections = NULL;
            prog->freeGlob = 0;
            argc = 0;

            argvAlloced = 5;
            prog->argv = malloc(sizeof(*prog->argv) * argvAlloced);
            prog->argv[0] = ++buf;

            src++;
            while (*src && isspace(*src)) src++;

            if (!*src) {
                fprintf(stderr, "empty command in pipe\n");
                return 1;
            }
            src--;              /* we'll ++ it at the end of the loop */

            break;

          case '&':                         /* background */
            *isBg = 1;
          case ';':                         /* multiple commands */
            done = 1;
            returnCommand = *commandPtr + (src - *commandPtr) + 1;
            break;

          case '\\':
            src++;
            if (!*src) {
                freeJob(job);
                fprintf(stderr, "character expected after \\\n");
                return 1;
            }
            if (*src == '*' || *src == '[' || *src == ']' || *src == '?')
                *buf++ = '\\';
            /* fallthrough */
          default:
            *buf++ = *src;
        }

        src++;
    }

    if (*prog->argv[argc]) {
        argc++;
        globLastArgument(prog, &argc, &argvAlloced);
    }
    if (!argc) {
        freeJob(job);
        return 0;
    }
    prog->argv[argc] = NULL;

    if (!returnCommand) {
        job->text = malloc(strlen(*commandPtr) + 1);
        strcpy(job->text, *commandPtr);
    } else {
        /* This leaves any trailing spaces, which is a bit sloppy */

        count = returnCommand - *commandPtr;
        job->text = malloc(count + 1);
        strncpy(job->text, *commandPtr, count);
        job->text[count] = '\0';
    }

    *commandPtr = returnCommand;

    return 0;
}
示例#12
0
文件: ack.c 项目: lamby/pkg-disque
/* This function is called by cluster.c every time we receive a GOTACK message
 * about a job we know. */
void gotAckReceived(clusterNode *sender, job *job, int known) {
    /* A dummy ACK is an acknowledged job that we created just becakse a client
     * send us ACKJOB about a job we were not aware. */
    int dummy_ack = dictSize(job->nodes_delivered) == 0;

    serverLog(LL_VERBOSE,"RECEIVED GOTACK FROM %.40s FOR JOB %.48s",
        sender->name, job->id);

    /* We should never receive a GOTACK for a job which is not acknowledged,
     * but it is more robust to handle it explicitly. */
    if (job->state != JOB_STATE_ACKED) return;

    /* If this is a dummy ACK, and we reached a node that knows about this job,
     * it's up to it to perform the garbage collection, so we can forget about
     * this job and reclaim memory. */
    if (dummy_ack && known) {
        serverLog(LL_VERBOSE,"Deleting %.48s: authoritative node reached",
            job->id);
        unregisterJob(job);
        freeJob(job);
        return;
    }

    /* If the sender knows about the job, or if we have the sender in the list
     * of nodes that may have the job (even if it no longer remembers about
     * the job), we do two things:
     *
     * 1) Add the node to the list of nodes_delivered. It is likely already
     *    there... so this should be useless, but is a good invariant
     *    to enforce.
     * 2) Add the node to the list of nodes that acknowledged the ACK. */
    if (known || dictFind(job->nodes_delivered,sender->name) != NULL) {
        dictAdd(job->nodes_delivered,sender->name,sender);
        /* job->nodes_confirmed exists if we started a job garbage collection,
         * but we may receive GOTACK messages in other conditions sometimes,
         * since we reply with SETACK to QUEUED and WILLQUEUE if the job is
         * acknowledged but we did not yet started to GC. So we need to test
         * if the hash table actually exists. */
        if (job->nodes_confirmed)
            dictAdd(job->nodes_confirmed,sender->name,sender);
    }

    /* If our job is actually a dummy ACK, we are still interested to collect
     * all the nodes in the cluster that reported they don't have a clue:
     * eventually if everybody in the cluster has no clue, we can safely remove
     * the dummy ACK. */
    if (!known && dummy_ack) {
        dictAdd(job->nodes_confirmed,sender->name,sender);
        if (dictSize(job->nodes_confirmed) >= dictSize(server.cluster->nodes))
        {
            serverLog(LL_VERBOSE,
                "Deleting %.48s: dummy ACK not known cluster-wide",
                job->id);
            unregisterJob(job);
            freeJob(job);
            return;
        }
    }

    /* Finally the common case: our SETACK reached everybody. Broadcast
     * a DELJOB to all the nodes involved, and delete the job. */
    if (!dummy_ack && job->nodes_confirmed &&
         dictSize(job->nodes_confirmed) >= dictSize(job->nodes_delivered))
    {
        serverLog(LL_VERBOSE,
            "Deleting %.48s: All nodes involved acknowledged the job",
            job->id);
        clusterBroadcastDelJob(job);
        unregisterJob(job);
        freeJob(job);
        return;
    }
}
示例#13
0
void notifFileUnavailable(t_job *job) {
	log_error(logger, "|JOB %d| Failed: One file is unavailable", job->id);
	sendDieOrder(job->socket, COMMAND_RESULT_FILEUNAVAILABLE);
	freeJob(job);
	pthread_exit(NULL);
}