int ThreadPoolAdd(ThreadPool *tp, ThreadPoolJob *job, int *jobId) { int rc = EOUTOFMEM; int tempId = -1; long totalJobs; ThreadPoolJob *temp = NULL; if (!tp || !job) return EINVAL; ithread_mutex_lock(&tp->mutex); totalJobs = tp->highJobQ.size + tp->lowJobQ.size + tp->medJobQ.size; if (totalJobs >= tp->attr.maxJobsTotal) { fprintf(stderr, "total jobs = %ld, too many jobs", totalJobs); goto exit_function; } if (!jobId) jobId = &tempId; *jobId = INVALID_JOB_ID; temp = CreateThreadPoolJob(job, tp->lastJobId, tp); if (!temp) goto exit_function; switch (job->priority) { case HIGH_PRIORITY: if (ListAddTail(&tp->highJobQ, temp)) rc = 0; break; case MED_PRIORITY: if (ListAddTail(&tp->medJobQ, temp)) rc = 0; break; default: if (ListAddTail(&tp->lowJobQ, temp)) rc = 0; } /* AddWorker if appropriate */ AddWorker(tp); /* Notify a waiting thread */ if (rc == 0) ithread_cond_signal(&tp->condition); else FreeThreadPoolJob(tp, temp); *jobId = tp->lastJobId++; exit_function: ithread_mutex_unlock(&tp->mutex); return rc; }
BOOL ReadMacro(HPTR hpBuf, LPLIST lpMacroList, BOOL fReadFirstPacketOnly) /***********************************************************************/ { LPTSTR lpCommand; MACRO_FILE_HANDLE fh; LPCMDPKT lpCmdPkt; BOOL fError; // zero out the list ListInit(lpMacroList); // Allocate a buffer to read the commands into if (!(lpCommand = (LPTSTR)Alloc(MAX_CMD_LEN))) { Message(IDS_EMEMALLOC); return(FALSE); } while (lpCmdPkt = ReadPacket(&hpBuf, lpCommand, &fError)) { ListAddTail(lpMacroList, lpCmdPkt); if (fReadFirstPacketOnly) break; } FreeUp(lpCommand); if (fError) { DestroyPacketList(lpMacroList); return(FALSE); } return(TRUE); }
static void *IMalloc_Alloc( IMalloc *self, uint32 cBytes ) { AllocNode *an; /* IMalloc requires us to implement the DidAlloc() function, * which returns non-zero if we allocated a particular chunk * of memory. * * In order to properly implement that functionality, this * code allocates the requested memory, and adds that memory * to a doubly-linked list, maintained internally as part of * the object's state. This way, we have a record of which * chunks of memory we did and did not allocate. */ an = (AllocNode *)malloc( cBytes + sizeof( AllocNode ) ); if( an != NULL ) { /* Fill in some bookkeeping information. */ an -> size = cBytes; /* For the IMalloc::GetSize() function */ LockAllocList(); ListAddTail( &allocList, (Node *)an ); UnlockAllocList(); /* Now advance "an" to point to the memory requested by the client */ an++; } return (void *)an; }
BOOL ReadMacro(LPTSTR lpFileName, LPLIST lpMacroList, BOOL fReadFirstPacketOnly) /***********************************************************************/ { LPTSTR lpCommand; MACRO_FILE_HANDLE fh; LPCMDPKT lpCmdPkt; BOOL fError; FNAME OEMName; // zero out the list ListInit(lpMacroList); // Open the macro file #ifdef BUFFERED_IO AnsiToOem(lpFileName, OEMName); fh = fopen(OEMName, _T("rb")); if (fh == NULL) #else fh = FileOpen(lpFileName, FO_READ); if (fh == MACRO_FILE_HANDLE_INVALID) #endif { Message(IDS_EOPEN, lpFileName); return(FALSE); } // Allocate a buffer to read the commands into if (!(lpCommand = (LPTSTR)Alloc(MAX_CMD_LEN))) { #ifdef BUFFERED_IO fclose(fh); #else FileClose(fh); #endif Message(IDS_EMEMALLOC); return(FALSE); } AstralCursor(IDC_WAIT); while (lpCmdPkt = ReadPacket(fh, lpCommand, &fError)) { ListAddTail(lpMacroList, lpCmdPkt); if (fReadFirstPacketOnly) break; } AstralCursor(NULL); FreeUp(lpCommand); #ifdef BUFFERED_IO fclose(fh); #else FileClose(fh); #endif if (fError) { DestroyPacketList(lpMacroList); return(FALSE); } return(TRUE); }
void CgiListMake(const Cgi cgi) { struct pair *psp; assert(cgi != NULL); while((psp = CgiNextValue(cgi)) != NULL) ListAddTail(&cgi->vars,&psp->node); }
/* Creates a new game for the gamelist. */ static int GameListNewGame (ListGame **listGamePtr) { if (!(*listGamePtr = (ListGame *) GameListCreate())) { GameListFree(&gameList); return(ENOMEM); } ListAddTail(&gameList, (ListNode *) *listGamePtr); return(0); }
static void *IMalloc_Realloc( IMalloc *self, void *pv, uint32 cBytes ) { AllocNode *an1 = ( (AllocNode *)pv ) - 1; AllocNode *an2; /* * Unlike the other memory allocation functions, we must lock the * list for the entire duration of the realloc operation. This is * because we must, essentially, perform a "read-modify-write" * operation on the list, and it must be atomic. * * The reason is realloc() *could* relocate a chunk of data, rather * than extending a chunk in-place. As a result, we must remove the * allocated node from the list, realloc() it, and then place it back * onto the list. */ LockAllocList(); NodeRemove( (Node *)an1 ); an2 = (AllocNode *)realloc( an1, cBytes + sizeof( AllocNode ) ); if( an2 != NULL ) { an2 -> size = cBytes; ListAddTail( &allocList, (Node *)an2 ); UnlockAllocList(); return (void *)( an2 + 1 ); } else { ListAddTail( &allocList, (Node *)an1 ); UnlockAllocList(); return NULL; } }
/**************************************************************************** * Function: BumpPriority * * Description: * Determines whether any jobs * need to be bumped to a higher priority Q and bumps them. * * tp->mutex must be locked. * Internal Only. * Parameters: * ThreadPool *tp *****************************************************************************/ static void BumpPriority( ThreadPool *tp ) { int done = 0; struct timeval now; unsigned long diffTime = 0; ThreadPoolJob *tempJob = NULL; assert( tp != NULL ); gettimeofday(&now, NULL); while( !done ) { if( tp->medJobQ.size ) { tempJob = ( ThreadPoolJob *) tp->medJobQ.head.next->item; diffTime = DiffMillis( &now, &tempJob->requestTime ); if( diffTime >= ( tp->attr.starvationTime ) ) { // If job has waited longer than the starvation time // bump priority (add to higher priority Q) StatsAccountMQ( tp, diffTime ); ListDelNode( &tp->medJobQ, tp->medJobQ.head.next, 0 ); ListAddTail( &tp->highJobQ, tempJob ); continue; } } if( tp->lowJobQ.size ) { tempJob = ( ThreadPoolJob *) tp->lowJobQ.head.next->item; diffTime = DiffMillis( &now, &tempJob->requestTime ); if( diffTime >= ( tp->attr.maxIdleTime ) ) { // If job has waited longer than the starvation time // bump priority (add to higher priority Q) StatsAccountLQ( tp, diffTime ); ListDelNode( &tp->lowJobQ, tp->lowJobQ.head.next, 0 ); ListAddTail( &tp->medJobQ, tempJob ); continue; } } done = 1; } }
static void s_Dmscp_Register_ServiceCalback(t_DMC_SERVICE_UPDATED_CALLBACK callback, int hnd) { int *p = (int*)malloc( sizeof(int) *2 ); HT_DBG_FUNC_START(HT_MOD_DMC, HT_BIT_MANY,(int)callback, NULL); sem_wait(&(s_dmscp_service_updated_lock)); p[0] = (int)callback; p[1] = hnd; ListAddTail( &s_dmscp_service_updated_list, p ); sem_post(&(s_dmscp_service_updated_lock)); HT_DBG_FUNC_END(hnd, NULL); }
/*-------------------------------------------------*/ static void s_Add_Object(char *buf, int IsPlayback) { HT_DBG_FUNC_START(HT_MOD_IPC, HT_BIT_MANY, 0, buf); t_FAKE_OBJ *p = (t_FAKE_OBJ*)malloc(sizeof(t_FAKE_OBJ)); // HT_DBG_FUNC(p, "p = "); p->IsPlayback = IsPlayback; // HT_DBG_FUNC(p, "p = "); p->handle = atoi(buf); // HT_DBG_FUNC(p, "p = "); ListAddTail(&s_object_list, p); // HT_DBG_FUNC(p, "p = "); sprintf(buf, "%d", (int)p); HT_DBG_FUNC_END((int)p, "fake = "); }
void RFC822HeadersRead(FILE *in,const List *list) { char *line; char *t; struct pair *ppair; assert(in != NULL); assert(list != NULL); while((line = RFC822LineRead(in)) != NULL) { t = line; ppair = PairNew(&t,':','\0'); ppair->name = trim_space(ppair->name); ppair->value = trim_space(ppair->value); up_string(ppair->name); ListAddTail((List *)list,&ppair->node); free(line); } }
// 说明:加入就绪列表 void TaskAddReady(TASK *task) { ListAddTail(&list_ready_tasks, &task->list_ready); }
int SearchByTarget(int Mx, char *St, void *Cookie) { char errorBuffer[ERROR_BUFFER_LEN]; int *id = NULL; int ret = 0; char ReqBufv4[BUFSIZE]; #ifdef UPNP_ENABLE_IPV6 char ReqBufv6[BUFSIZE]; char ReqBufv6UlaGua[BUFSIZE]; #endif struct sockaddr_storage __ss_v4; #ifdef UPNP_ENABLE_IPV6 struct sockaddr_storage __ss_v6; #endif struct sockaddr_in *destAddr4 = (struct sockaddr_in *)&__ss_v4; #ifdef UPNP_ENABLE_IPV6 struct sockaddr_in6 *destAddr6 = (struct sockaddr_in6 *)&__ss_v6; #endif fd_set wrSet; SsdpSearchArg *newArg = NULL; int timeTillRead = 0; int handle; struct Handle_Info *ctrlpt_info = NULL; enum SsdpSearchType requestType; unsigned long addrv4 = inet_addr(gIF_IPV4); SOCKET max_fd = 0; int retVal; /*ThreadData *ThData; */ ThreadPoolJob job; memset(&job, 0, sizeof(job)); requestType = ssdp_request_type1(St); if (requestType == SSDP_SERROR) return UPNP_E_INVALID_PARAM; UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__, "Inside SearchByTarget\n"); timeTillRead = Mx; if (timeTillRead < MIN_SEARCH_TIME) timeTillRead = MIN_SEARCH_TIME; else if (timeTillRead > MAX_SEARCH_TIME) timeTillRead = MAX_SEARCH_TIME; retVal = CreateClientRequestPacket(ReqBufv4, sizeof(ReqBufv4), timeTillRead, St, AF_INET); if (retVal != UPNP_E_SUCCESS) return retVal; #ifdef UPNP_ENABLE_IPV6 retVal = CreateClientRequestPacket(ReqBufv6, sizeof(ReqBufv6), timeTillRead, St, AF_INET6); if (retVal != UPNP_E_SUCCESS) return retVal; retVal = CreateClientRequestPacketUlaGua(ReqBufv6UlaGua, sizeof(ReqBufv6UlaGua), timeTillRead, St, AF_INET6); if (retVal != UPNP_E_SUCCESS) return retVal; #endif memset(&__ss_v4, 0, sizeof(__ss_v4)); destAddr4->sin_family = (sa_family_t)AF_INET; inet_pton(AF_INET, SSDP_IP, &destAddr4->sin_addr); destAddr4->sin_port = htons(SSDP_PORT); #ifdef UPNP_ENABLE_IPV6 memset(&__ss_v6, 0, sizeof(__ss_v6)); destAddr6->sin6_family = (sa_family_t)AF_INET6; inet_pton(AF_INET6, SSDP_IPV6_SITELOCAL, &destAddr6->sin6_addr); destAddr6->sin6_port = htons(SSDP_PORT); destAddr6->sin6_scope_id = gIF_INDEX; #endif /* add search criteria to list */ HandleLock(); if (GetClientHandleInfo(&handle, &ctrlpt_info) != HND_CLIENT) { HandleUnlock(); return UPNP_E_INTERNAL_ERROR; } newArg = (SsdpSearchArg *) malloc(sizeof(SsdpSearchArg)); newArg->searchTarget = strdup(St); newArg->cookie = Cookie; newArg->requestType = requestType; id = (int *)malloc(sizeof(int)); TPJobInit(&job, (start_routine) searchExpired, id); TPJobSetPriority(&job, MED_PRIORITY); TPJobSetFreeFunction(&job, (free_routine) free); /* Schedule a timeout event to remove search Arg */ TimerThreadSchedule(&gTimerThread, timeTillRead, REL_SEC, &job, SHORT_TERM, id); newArg->timeoutEventId = *id; ListAddTail(&ctrlpt_info->SsdpSearchList, newArg); HandleUnlock(); /* End of lock */ FD_ZERO(&wrSet); if (gSsdpReqSocket4 != INVALID_SOCKET) { setsockopt(gSsdpReqSocket4, IPPROTO_IP, IP_MULTICAST_IF, (char *)&addrv4, sizeof(addrv4)); FD_SET(gSsdpReqSocket4, &wrSet); max_fd = max(max_fd, gSsdpReqSocket4); } #ifdef UPNP_ENABLE_IPV6 if (gSsdpReqSocket6 != INVALID_SOCKET) { setsockopt(gSsdpReqSocket6, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char *)&gIF_INDEX, sizeof(gIF_INDEX)); FD_SET(gSsdpReqSocket6, &wrSet); max_fd = max(max_fd, gSsdpReqSocket6); } #endif ret = select(max_fd + 1, NULL, &wrSet, NULL, NULL); if (ret == -1) { strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN); UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__, "SSDP_LIB: Error in select(): %s\n", errorBuffer); shutdown(gSsdpReqSocket4, SD_BOTH); UpnpCloseSocket(gSsdpReqSocket4); #ifdef UPNP_ENABLE_IPV6 shutdown(gSsdpReqSocket6, SD_BOTH); UpnpCloseSocket(gSsdpReqSocket6); #endif return UPNP_E_INTERNAL_ERROR; } #ifdef UPNP_ENABLE_IPV6 if (gSsdpReqSocket6 != INVALID_SOCKET && FD_ISSET(gSsdpReqSocket6, &wrSet)) { int NumCopy = 0; while (NumCopy < NUM_SSDP_COPY) { UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__, ">>> SSDP SEND M-SEARCH >>>\n%s\n", ReqBufv6UlaGua); sendto(gSsdpReqSocket6, ReqBufv6UlaGua, strlen(ReqBufv6UlaGua), 0, (struct sockaddr *)&__ss_v6, sizeof(struct sockaddr_in6)); NumCopy++; imillisleep(SSDP_PAUSE); } NumCopy = 0; inet_pton(AF_INET6, SSDP_IPV6_LINKLOCAL, &destAddr6->sin6_addr); while (NumCopy < NUM_SSDP_COPY) { UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__, ">>> SSDP SEND M-SEARCH >>>\n%s\n", ReqBufv6); sendto(gSsdpReqSocket6, ReqBufv6, strlen(ReqBufv6), 0, (struct sockaddr *)&__ss_v6, sizeof(struct sockaddr_in6)); NumCopy++; imillisleep(SSDP_PAUSE); } } #endif /* IPv6 */ if (gSsdpReqSocket4 != INVALID_SOCKET && FD_ISSET(gSsdpReqSocket4, &wrSet)) { int NumCopy = 0; while (NumCopy < NUM_SSDP_COPY) { UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__, ">>> SSDP SEND M-SEARCH >>>\n%s\n", ReqBufv4); sendto(gSsdpReqSocket4, ReqBufv4, strlen(ReqBufv4), 0, (struct sockaddr *)&__ss_v4, sizeof(struct sockaddr_in)); NumCopy++; imillisleep(SSDP_PAUSE); } } return 1; }
/************************************************************************ * Function: TimerThreadSchedule * * Description: * Schedules an event to run at a specified time. * * Parameters: * timer - valid timer thread pointer. * time_t - time of event. * either in absolute seconds, * or relative seconds in the future. * timeoutType - either ABS_SEC, or REL_SEC. * if REL_SEC, then the event * will be scheduled at the * current time + REL_SEC. * * func - function to schedule * arg - argument to function * priority - priority of job. * id - id of timer event. (out) * Return: * 0 on success, nonzero on failure * EOUTOFMEM if not enough memory to schedule job ************************************************************************/ int TimerThreadSchedule( TimerThread * timer, time_t timeout, TimeoutType type, ThreadPoolJob * job, Duration duration, int *id ) { int rc = EOUTOFMEM; int found = 0; int tempId = 0; ListNode *tempNode = NULL; TimerEvent *temp = NULL; TimerEvent *newEvent = NULL; assert( timer != NULL ); assert( job != NULL ); if( ( timer == NULL ) || ( job == NULL ) ) { return EINVAL; } CalculateEventTime( &timeout, type ); ithread_mutex_lock( &timer->mutex ); if( id == NULL ) id = &tempId; ( *id ) = INVALID_EVENT_ID; newEvent = CreateTimerEvent( timer, job, duration, timeout, timer->lastEventId ); if( newEvent == NULL ) { ithread_mutex_unlock( &timer->mutex ); return rc; } tempNode = ListHead( &timer->eventQ ); //add job to Q //Q is ordered by eventTime //with the head of the Q being the next event while( tempNode != NULL ) { temp = ( TimerEvent * ) tempNode->item; if( temp->eventTime >= timeout ) { if( ListAddBefore( &timer->eventQ, newEvent, tempNode ) != NULL ) rc = 0; found = 1; break; } tempNode = ListNext( &timer->eventQ, tempNode ); } //add to the end of Q if( !found ) { if( ListAddTail( &timer->eventQ, newEvent ) != NULL ) rc = 0; } //signal change in Q if( rc == 0 ) { ithread_cond_signal( &timer->condition ); } else { FreeTimerEvent( timer, newEvent ); } ( *id ) = timer->lastEventId++; ithread_mutex_unlock( &timer->mutex ); return rc; }
LOCAL BOOL SetupMacro(LPQUEUEITEM lpQueueItem) /***********************************************************************/ { LPCMDPKT lpCmdPkt; FNAME szFileName; lpCmdPkt = CreatePacket(IDS_CMD_LOADFILE, &lpQueueItem->parms, TRUE); if (!lpCmdPkt) goto MemError; ListAddHead(&lpQueueItem->PacketList, lpCmdPkt); // create the new filename // add a save command to the end if necessary if (Macro.BatchSave == IDC_SAVETOORIGINAL) lstrcpy(szFileName, lpQueueItem->szFileName); else if (Macro.BatchSave == IDC_SAVETODIR) { lstrcpy(szFileName, Macro.BatchDir); lstrcat(szFileName, filename(lpQueueItem->szFileName)); } else if (Macro.BatchSave == IDC_SAVETOALBUM) { lstrcpy(szFileName, Browser.AlbumFileDir); lstrcat(szFileName, filename(lpQueueItem->szFileName)); } // if we are changing the file type, then change the extension if (Macro.fBatchChangeType && (Macro.BatchSave == IDC_SAVETODIR || Macro.BatchSave == IDC_SAVETOALBUM)) { STRING szExt; LookupExtension(LocalFileType(Macro.BatchFileType), szExt); stripext(szFileName); lstrcat(szFileName, szExt); } // check to make sure we are not saving to PCD and overwrite warning if (Macro.BatchSave != IDC_NOSAVE) { if (!CheckPCDSave(szFileName)) return(FALSE); if (Macro.BatchSave != IDC_SAVETOORIGINAL) { if (FileExists(szFileName)) { if (AstralOKCancel (IDS_OVERWRITEIMAGE, (LPTSTR)szFileName) != IDOK) return(FALSE); } } } if (Macro.BatchSave == IDC_SAVETOALBUM) { // get a path name from the browser SAVETOALBUM_PARMS parms; lstrcpy(parms.szAlbum, Macro.BatchAlbum); lstrcpy(parms.szFileName, szFileName); parms.idFileType = GetPPFileType(parms.szFileName); parms.idDataType = 0; parms.EPSOptions = EPSOptions; parms.TIFFOptions = TIFFOptions; parms.TGAOptions = TGAOptions; parms.JPEGOptions = JPEGOptions; parms.PPFFOptions = PPFFOptions; parms.AVIOptions = AVIOptions; // create a command list for the load command lpCmdPkt = CreatePacket(IDS_CMD_SAVETOALBUM, &parms, TRUE); if (!lpCmdPkt) goto MemError; ListAddTail(&lpQueueItem->PacketList, lpCmdPkt); } else if (Macro.BatchSave != IDC_NOSAVE) { SAVEFILE_PARMS parms; lstrcpy(parms.szFileName, szFileName); parms.idFileType = GetPPFileType(parms.szFileName); parms.idDataType = 0; parms.EPSOptions = EPSOptions; parms.TIFFOptions = TIFFOptions; parms.TGAOptions = TGAOptions; parms.JPEGOptions = JPEGOptions; parms.PPFFOptions = PPFFOptions; parms.AVIOptions = AVIOptions; // create a command list for the load command lpCmdPkt = CreatePacket(IDS_CMD_SAVEFILE, &parms, TRUE); if (!lpCmdPkt) goto MemError; ListAddTail(&lpQueueItem->PacketList, lpCmdPkt); } if (Macro.fBatchClose) { CMD_PARMS parms; // create a command list for the load command lpCmdPkt = CreatePacket(IDS_CMD_CLOSE, &parms, TRUE); if (!lpCmdPkt) goto MemError; ListAddTail(&lpQueueItem->PacketList, lpCmdPkt); } return(TRUE); MemError: Message(IDS_EMEMALLOC); return(FALSE); }
BOOL PlayMacro(LPCMDLIST lpCmdList, LPTSTR lpFileName, int nRepeat, BOOL fSequenceAll, LPLIST lpMacroList, HWND hParent, int PhotoCDResOverride, LPTSTR lpMacroName) /***********************************************************************/ { LPIMAGE lpImage; LPCMDLIST lpNewList; int nActivates, iCount; ITEMID idCommand; STRING szString, szAppName; BOOL fError; BOOL fSequence, fCmdSequence, fCopyPackets; LIST MacroList; LPCMDPKT lpCmdPkt, lpNextPkt; MACROSETUP Setup; COMMAND_TYPE CommandType; HWND hDlg = NULL; lpAbortProc = NULL; if (!hParent) hParent = PictPubApp.Get_hWndAstral(); // see if we need to copy our packets fCopyPackets = nRepeat > 1; if (!lpMacroList) { // read in the entire macro file for faster processing if (!ReadMacro(lpFileName, &MacroList)) return(FALSE); lpMacroList = &MacroList; } // count the number of activates in the macro file // because it affects sequencing nActivates = CountType(lpMacroList, CT_ACTIVATE); // turn of macro play mode and tell the world MacroMode = MM_PLAY; if ( AstralStrEx( IDS_APPNAME, szAppName, sizeof(szAppName) ) ) { if ( AstralStrEx( IDS_MACROPLAY, szString, sizeof(szString) ) ) { lstrcat( szAppName, szString ); SetWindowText( PictPubApp.Get_hWndAstral(), szAppName ); } } // reset untitled number so that if a macro is played it // can deal with untitled images the same Control.UntitledNo = 0; // If no command list passed in to work on (Macro Batch Mode) // then get command list for active image if (!lpCmdList) { if (lpImage = GetActiveImage()) lpCmdList = lpImage->lpCmdList; else lpCmdList = NULL; } // See if the macro contains any low res loads and // if so ask to user if he'd like to convert them // to hi res loads and if so do the convert if (FindCommand(lpMacroList, IDS_CMD_LOWRESLOAD)) if (AstralAffirm(IDS_CONVERTLOWRES)) if (!ConvertLowResLoad(lpMacroList)) { DestroyPacketList(lpMacroList); return(FALSE); } // disable all mouse and keyboard input during macro play EnableWindow(hParent, FALSE); // if not in a threading environment and caller wants us // to display a progress dialog, then set it up and do it if (!Control.UseThreading) { iCount = ListGetCount(lpMacroList) - nActivates; iCount *= nRepeat; Setup.iTotal = iCount; Setup.idDialog = IDD_MACRO_STATUS; Setup.lpFileName = NULL; hDlg = AstralDlgParam( YES, PictPubApp.GetResourceHandle(), hParent, IDD_MACRO_STATUS, DlgMacroStatusProc, (LPARAM)(LPVOID)&Setup ); if (hDlg) { if (lpMacroName) { STRING szString; GetWindowText(hDlg, szString, sizeof(szString)); lstrcat(szString, _T(" - ")); lstrcat(szString, lpMacroName); SetWindowText(hDlg, szString); } UpdateWindow(hDlg); } } // Repeat macro nRepeat number of times fError = FALSE; while (--nRepeat >= 0 && !fError) { if (lpAbortProc && (*lpAbortProc)()) break; // back to beginning of macro file lpNextPkt = (LPCMDPKT)ListGetHead(lpMacroList); // initialize sequencing fSequence = fSequenceAll; while (!fError && lpNextPkt) { if (lpAbortProc && (*lpAbortProc)()) { fError = TRUE; break; } // get the packet to work on if (fCopyPackets) { lpCmdPkt = CopyPacket(lpNextPkt); if (!lpCmdPkt) { fError = TRUE; break; } } else { ListUnlink(lpMacroList, lpNextPkt); lpCmdPkt = lpNextPkt; } // get command id and parms for this command idCommand = lpCmdPkt->idCommand; // Find out whether this command requires sequencing // set it here, so command can change it if needed before // we actually set fSequence fCmdSequence = GetCommandSequence(idCommand); CommandType = GetCommandType(idCommand); // Handle the different types of commands switch (CommandType) { case CT_LOAD: // create new command list for load lpNewList = CreateCommandList(); if (lpNewList) { ListAddTail(&lpNewList->PacketList, lpCmdPkt); // if we already have a command list containing commands, // kick off the execution of those commands before we // switch to the new command list if (lpCmdList && !ListIsEmpty(&lpCmdList->PacketList)) { PlaybackCommands(lpCmdList); // if some command in the command list affects // sequencing force the whole command list to // be processed if (fSequence) { FlushCommands(lpCmdList); fSequence = fSequenceAll; } } // setup new command list for us to work with lpCmdList = lpNewList; lpCmdList->PhotoCDResOverride = PhotoCDResOverride; // If there are any activates in this macro make sure a // command that creates an image processes immediately if (nActivates) { PlaybackCommands(lpCmdList); FlushCommands(lpCmdList); fSequence = fSequenceAll; fCmdSequence = NO; // already sequenced } } break; case CT_COPY: // Make sure we have a command list to work with if (!lpCmdList) { Message(IDS_NOIMAGETOWORKON); fError = TRUE; break; } // Just add this command to the command list ListAddTail(&lpCmdList->PacketList, lpCmdPkt); // If there are any activates in this macro make sure a // command that creates an image processes immediately if (nActivates) { PlaybackCommands(lpCmdList); FlushCommands(lpCmdList); fSequence = fSequenceAll; fCmdSequence = NO; // already sequenced } break; case CT_SAVE: case CT_EDIT: case CT_MASK: case CT_MODE: case CT_EDITUNDO: case CT_MASKUNDO: case CT_EDITOBJ: case CT_CLOSE: // Make sure we have a command list to work with if (!lpCmdList) { Message(IDS_NOIMAGETOWORKON); fError = TRUE; break; } if (CommandType == CT_SAVE) { PlaybackCommands(lpCmdList); if (!lpCmdList->ThreadData.lpImage) { Message(IDS_NOIMAGETOWORKON); fError = TRUE; break; } } // Just add this command to the command list ListAddTail(&lpCmdList->PacketList, lpCmdPkt); if (CommandType != CT_CLOSE) break; case CT_ACTIVATE: // Program or commands that affect window activation // are processed here switch (idCommand) { case IDS_CMD_CLOSE: case IDS_CMD_ACTIVATEWINDOW: { // if we already have a command list containing commands, // kick of the execution of those commands before we // switch to the new command list if (lpCmdList && !ListIsEmpty(&lpCmdList->PacketList)) { PlaybackCommands(lpCmdList); // if some command in the command list affects // sequencing force the whole command list to // be processed if (fSequence) { FlushCommands(lpCmdList); fSequence = fSequenceAll; } } // if this was a close command, then wack the command list pointer if (idCommand == IDS_CMD_CLOSE) lpCmdList = NULL; else { // now process the activate and get a new command list lpNewList = ProgActivateWindow( (LPACTIVATEWINDOW_PARMS)lpCmdPkt->lpParms); // setup the new command list if we got one if (lpNewList) lpCmdList = lpNewList; else { CommandError(idCommand); fError = TRUE; } // activate don't go through command processing // so we have to free it up here FreeUpPacket(lpCmdPkt); } } break; default: break; } break; default: break; } // if command just handled requires sequencing // set sequencing flag if (fCmdSequence) fSequence = YES; if (fCopyPackets) // get next command packet in macro list lpNextPkt = (LPCMDPKT)ListGetNext(lpNextPkt); else // head of list will be next one if we're not copying lpNextPkt = (LPCMDPKT)ListGetHead(lpMacroList); } } // get rid of macro list DestroyPacketList(lpMacroList); // if we already have a command list containing commands, // kick off the execution of those commands if (lpCmdList && !ListIsEmpty(&lpCmdList->PacketList)) { PlaybackCommands(lpCmdList); if (fSequenceAll) FlushCommands(lpCmdList); } // turn off the macro mode EnableWindow(hParent, TRUE); if ( AstralStrEx( IDS_APPNAME, szAppName, sizeof(szAppName) ) ) SetWindowText( PictPubApp.Get_hWndAstral(), szAppName ); // if we have a progress dialog, nuke it if (hDlg) AstralDlgEnd(hDlg, TRUE); // if we are display the macro status for another modal dialog // make sure the main app stuff is still disabled if (hParent != PictPubApp.Get_hWndAstral()) { EnableOverlappedWindow( PictPubApp.Get_hWndAstral(), FALSE ); EnableWindow(PictPubApp.Get_hWndAstral(), FALSE); } MacroMode = MM_NONE; return(TRUE); }
void PlayBatchMacro(LPLIST lpQueueList) /***********************************************************************/ { LPQUEUEITEM lpQueueItem = NULL; LPMACROITEM lpMacroItem; FNAME szFileName; LIST TempList; BOOL fError = TRUE; fPCDNotice = FALSE; while (TRUE) { if (lpQueueItem) lpQueueItem = (LPQUEUEITEM)ListGetNext(lpQueueItem); else lpQueueItem = (LPQUEUEITEM)ListGetHead(lpQueueList); if (!lpQueueItem) { fError = FALSE; break; } ListInit(&lpQueueItem->PacketList); // create a command list for the load command if (!CreateLoadFileParms(0, lpQueueItem->szFileName, TRUE, &lpQueueItem->cmsInfo, &lpQueueItem->PhotoCDResOverride, &lpQueueItem->parms)) continue; lpMacroItem = NULL; while (TRUE) { if (lpMacroItem) lpMacroItem = (LPMACROITEM)ListGetNext(lpMacroItem); else lpMacroItem = (LPMACROITEM)ListGetHead(&lpQueueItem->MacroList); if (!lpMacroItem) break; if ( !LookupExtFile( lpMacroItem->szMacro, szFileName, IDN_MACRO ) ) continue; // read in the entire macro file for faster processing if (!ReadMacro(szFileName, &TempList)) continue; if (MacroAnyLoadCommands(&TempList)) { Message(IDS_BADBATCHMACRO); DestroyPacketList(&TempList); continue; } ListAddTail(&lpQueueItem->PacketList, ListGetHead(&TempList)); } if (!SetupMacro(lpQueueItem)) break; } if (!fError) { if (EnableLogging(TRUE)) { lpQueueItem = NULL; while (!fError) { if (lpQueueItem) lpQueueItem = (LPQUEUEITEM)ListGetNext(lpQueueItem); else lpQueueItem = (LPQUEUEITEM)ListGetHead(lpQueueList); if (!lpQueueItem) break; if (!PlayMacro(NULL, NULL, 1, NO, &lpQueueItem->PacketList, NULL, lpQueueItem->PhotoCDResOverride)) break; } EnableLogging(FALSE); } } lpQueueItem = NULL; while (TRUE) { if (lpQueueItem) lpQueueItem = (LPQUEUEITEM)ListGetNext(lpQueueItem); else lpQueueItem = (LPQUEUEITEM)ListGetHead(lpQueueList); if (!lpQueueItem) break; DestroyPacketList(&lpQueueItem->PacketList); DestroyPtrList(&lpQueueItem->MacroList); } DestroyPtrList(lpQueueList); }
/* We take ownership of propertySet and will free it */ static int genaInitNotifyCommon( UpnpDevice_Handle device_handle, char *UDN, char *servId, DOMString propertySet, const Upnp_SID sid) { int ret = GENA_SUCCESS; int line = 0; int *reference_count = NULL; char *UDN_copy = NULL; char *servId_copy = NULL; char *headers = NULL; notify_thread_struct *thread_struct = NULL; subscription *sub = NULL; service_info *service = NULL; struct Handle_Info *handle_info; ThreadPoolJob *job = NULL; UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__, "GENA BEGIN INITIAL NOTIFY COMMON"); job = (ThreadPoolJob *)malloc(sizeof(ThreadPoolJob)); if (job == NULL) { line = __LINE__; ret = UPNP_E_OUTOF_MEMORY; goto ExitFunction; } memset(job, 0, sizeof(ThreadPoolJob)); reference_count = (int *)malloc(sizeof (int)); if (reference_count == NULL) { line = __LINE__; ret = UPNP_E_OUTOF_MEMORY; goto ExitFunction; } *reference_count = 0; UDN_copy = strdup(UDN); if (UDN_copy == NULL) { line = __LINE__; ret = UPNP_E_OUTOF_MEMORY; goto ExitFunction; } servId_copy = strdup(servId); if (servId_copy == NULL) { line = __LINE__; ret = UPNP_E_OUTOF_MEMORY; goto ExitFunction; } HandleLock(); if (GetHandleInfo(device_handle, &handle_info) != HND_DEVICE) { line = __LINE__; ret = GENA_E_BAD_HANDLE; goto ExitFunction; } service = FindServiceId(&handle_info->ServiceTable, servId, UDN); if (service == NULL) { line = __LINE__; ret = GENA_E_BAD_SERVICE; goto ExitFunction; } UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__, "FOUND SERVICE IN INIT NOTFY: UDN %s, ServID: %s", UDN, servId); sub = GetSubscriptionSID(sid, service); if (sub == NULL || sub->active) { line = __LINE__; ret = GENA_E_BAD_SID; goto ExitFunction; } UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__, "FOUND SUBSCRIPTION IN INIT NOTIFY: SID %s", sid); sub->active = 1; headers = AllocGenaHeaders(propertySet); if (headers == NULL) { line = __LINE__; ret = UPNP_E_OUTOF_MEMORY; goto ExitFunction; } /* schedule thread for initial notification */ thread_struct = (notify_thread_struct *)malloc(sizeof (notify_thread_struct)); if (thread_struct == NULL) { line = __LINE__; ret = UPNP_E_OUTOF_MEMORY; } else { *reference_count = 1; thread_struct->servId = servId_copy; thread_struct->UDN = UDN_copy; thread_struct->headers = headers; thread_struct->propertySet = propertySet; memset(thread_struct->sid, 0, sizeof(thread_struct->sid)); strncpy(thread_struct->sid, sid, sizeof(thread_struct->sid) - 1); thread_struct->ctime = time(0); thread_struct->reference_count = reference_count; thread_struct->device_handle = device_handle; TPJobInit(job, (start_routine)genaNotifyThread, thread_struct); TPJobSetFreeFunction(job, (free_routine)free_notify_struct); TPJobSetPriority(job, MED_PRIORITY); ret = ThreadPoolAdd(&gSendThreadPool, job, NULL); if (ret != 0) { if (ret == EOUTOFMEM) { line = __LINE__; ret = UPNP_E_OUTOF_MEMORY; } } else { ListNode *node = ListAddTail(&sub->outgoing, job); if (node != NULL) { ((ThreadPoolJob *)node->item)->jobId = STALE_JOBID; line = __LINE__; ret = GENA_SUCCESS; } else { line = __LINE__; ret = UPNP_E_OUTOF_MEMORY; } } } ExitFunction: if (ret != GENA_SUCCESS) { free(job); free(thread_struct); free(headers); ixmlFreeDOMString(propertySet); free(servId_copy); free(UDN_copy); free(reference_count); } HandleUnlock(); UpnpPrintf(UPNP_INFO, GENA, __FILE__, line, "GENA END INITIAL NOTIFY COMMON, ret = %d", ret); return ret; }
/* We take ownership of propertySet and will free it */ static int genaNotifyAllCommon( UpnpDevice_Handle device_handle, char *UDN, char *servId, DOMString propertySet) { int ret = GENA_SUCCESS; int line = 0; int *reference_count = NULL; char *UDN_copy = NULL; char *servId_copy = NULL; char *headers = NULL; notify_thread_struct *thread_struct = NULL; subscription *finger = NULL; service_info *service = NULL; struct Handle_Info *handle_info; UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__, "GENA BEGIN NOTIFY ALL COMMON"); /* Keep this allocation first */ reference_count = (int *)malloc(sizeof (int)); if (reference_count == NULL) { line = __LINE__; ret = UPNP_E_OUTOF_MEMORY; goto ExitFunction; } *reference_count = 0; UDN_copy = strdup(UDN); if (UDN_copy == NULL) { line = __LINE__; ret = UPNP_E_OUTOF_MEMORY; goto ExitFunction; } servId_copy = strdup(servId); if( servId_copy == NULL ) { line = __LINE__; ret = UPNP_E_OUTOF_MEMORY; goto ExitFunction; } headers = AllocGenaHeaders(propertySet); if (headers == NULL) { line = __LINE__; ret = UPNP_E_OUTOF_MEMORY; goto ExitFunction; } HandleLock(); if (GetHandleInfo(device_handle, &handle_info) != HND_DEVICE) { line = __LINE__; ret = GENA_E_BAD_HANDLE; } else { service = FindServiceId(&handle_info->ServiceTable, servId, UDN); if (service != NULL) { finger = GetFirstSubscription(service); while (finger) { ThreadPoolJob *job = NULL; ListNode *node; thread_struct = (notify_thread_struct *)malloc(sizeof (notify_thread_struct)); if (thread_struct == NULL) { line = __LINE__; ret = UPNP_E_OUTOF_MEMORY; break; } (*reference_count)++; thread_struct->reference_count = reference_count; thread_struct->UDN = UDN_copy; thread_struct->servId = servId_copy; thread_struct->headers = headers; thread_struct->propertySet = propertySet; memset(thread_struct->sid, 0, sizeof(thread_struct->sid)); strncpy(thread_struct->sid, finger->sid, sizeof(thread_struct->sid) - 1); thread_struct->ctime = time(0); thread_struct->device_handle = device_handle; maybeDiscardEvents(&finger->outgoing); job = (ThreadPoolJob *)malloc(sizeof(ThreadPoolJob)); if (job == NULL) { line = __LINE__; ret = UPNP_E_OUTOF_MEMORY; break; } memset(job, 0, sizeof(ThreadPoolJob)); TPJobInit(job, (start_routine)genaNotifyThread, thread_struct); TPJobSetFreeFunction(job, (free_routine)free_notify_struct); TPJobSetPriority(job, MED_PRIORITY); node = ListAddTail(&finger->outgoing, job); /* If there is only one element on the list (which we just added), need to kickstart the threadpool */ if (ListSize(&finger->outgoing) == 1) { ret = ThreadPoolAdd(&gSendThreadPool, job, NULL); if (ret != 0) { line = __LINE__; if (ret == EOUTOFMEM) { line = __LINE__; ret = UPNP_E_OUTOF_MEMORY; } break; } if (node) { ((ThreadPoolJob *)(node->item))->jobId = STALE_JOBID; } } finger = GetNextSubscription(service, finger); } } else { line = __LINE__; ret = GENA_E_BAD_SERVICE; } } ExitFunction: /* The only case where we want to free memory here is if the struct was never queued. Else, let the normal cleanup take place. reference_count is allocated first so it's ok to do nothing if it's 0 */ if (reference_count && *reference_count == 0) { free(headers); ixmlFreeDOMString(propertySet); free(servId_copy); free(UDN_copy); free(reference_count); } HandleUnlock(); UpnpPrintf(UPNP_INFO, GENA, __FILE__, line, "GENA END NOTIFY ALL COMMON, ret = %d", ret); return ret; }
/**************************************************************************** * Function: ThreadPoolAdd * * Description: * Adds a job to the thread pool. * Job will be run as soon as possible. * Parameters: * tp - valid thread pool pointer * func - ThreadFunction to run * arg - argument to function. * priority - priority of job. * jobId - id of job * duration - whether or not this is a persistent thread * free_function - function to use when freeing argument * Returns: * 0 on success, nonzero on failure * EOUTOFMEM if not enough memory to add job. *****************************************************************************/ int ThreadPoolAdd( ThreadPool *tp, ThreadPoolJob *job, int *jobId ) { int rc = EOUTOFMEM; int tempId = -1; int totalJobs; ThreadPoolJob *temp = NULL; assert( tp != NULL ); assert( job != NULL ); if( ( tp == NULL ) || ( job == NULL ) ) { return EINVAL; } ithread_mutex_lock( &tp->mutex ); assert( job->priority == LOW_PRIORITY || job->priority == MED_PRIORITY || job->priority == HIGH_PRIORITY ); totalJobs = tp->highJobQ.size + tp->lowJobQ.size + tp->medJobQ.size; if (totalJobs >= tp->attr.maxJobsTotal) { fprintf(stderr, "total jobs = %d, too many jobs", totalJobs); ithread_mutex_unlock( &tp->mutex ); return rc; } if( jobId == NULL ) { jobId = &tempId; } *jobId = INVALID_JOB_ID; temp = CreateThreadPoolJob( job, tp->lastJobId, tp ); if( temp == NULL ) { ithread_mutex_unlock( &tp->mutex ); return rc; } if( job->priority == HIGH_PRIORITY ) { if( ListAddTail( &tp->highJobQ, temp ) ) { rc = 0; } } else if( job->priority == MED_PRIORITY ) { if( ListAddTail( &tp->medJobQ, temp ) ) { rc = 0; } } else { if( ListAddTail( &tp->lowJobQ, temp ) ) { rc = 0; } } // AddWorker if appropriate AddWorker( tp ); // Notify a waiting thread if( rc == 0 ) { ithread_cond_signal( &tp->condition ); } else { FreeThreadPoolJob( tp, temp ); } *jobId = tp->lastJobId++; ithread_mutex_unlock( &tp->mutex ); return rc; }