/****************************************************************\ * Main window WM_COMMAND processing procedure *-------------------------------------------------------------- * * Name: MainCommand(mp1, mp2) * * Purpose: Calls the appropriate procedures that deal with * the selected menu item. * * Usage: Routine is called whenever a WM_COMMAND message * is posted to the main window. * * Method: a switch statement branches on the id of the * menu item that posted the message and the * appropriate action for that item is taken. * * Returns: * \****************************************************************/ VOID MainCommand(MPARAM mp1, MPARAM mp2) { switch(SHORT1FROMMP(mp1)) { case IDM_FILEEXIT: FileExit(); break; case IDM_OPTIONPURGE: iIndex = sTotalMsgs = 0; /* get memory thread, write priority 15 message to tell thread to purge Q */ DosWriteQueue(hqQ, IDM_OPTIONPURGE, 0UL, NULL, 15UL); MainPurgeWindow(); break; case IDM_HELPHELPFORHELP: HelpHelpForHelp(mp2); break; case IDM_HELPEXTENDED: HelpExtended(mp2); break; case IDM_HELPKEYS: HelpKeys(mp2); break; case IDM_HELPINDEX: HelpIndex(mp2); break; case IDM_HELPTUTORIAL: HelpTutorial(mp2); break; case IDM_HELPABOUT: HelpAbout(mp2); break; default: break; } } /* MainCommand() */
static void server_maintenance(void *vpArg) { int num_idle, num_needed; ULONG num_pending = 0; int threadnum; HQUEUE workq; ULONG rc; PID owner; rc = DosOpenQueue(&owner, &workq, apr_psprintf(pchild, "/queues/httpd/work.%d", getpid())); if (rc) { ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf, "unable to open work queue in maintenance thread"); return; } do { for (num_idle=0, threadnum=0; threadnum < HARD_THREAD_LIMIT; threadnum++) { num_idle += ap_scoreboard_image->servers[child_slot][threadnum].status == SERVER_READY; } DosQueryQueue(workq, &num_pending); num_needed = ap_min_spare_threads - num_idle + num_pending; if (num_needed > 0) { for (threadnum=0; threadnum < num_needed; threadnum++) { add_worker(); } } if (num_idle - num_pending > ap_max_spare_threads) { DosWriteQueue(workq, WORKTYPE_EXIT, 0, NULL, 0); } } while (DosWaitEventSem(shutdown_event, 500) == ERROR_TIMEOUT); }
static int SendExtQMsg ( USHORT usEvent, PVOID pData, ULONG ulLen ) { USHORT res; ULONG ulPID; HQUEUE hQueue; PVOID pItem; res=DosOpenQueue(&ulPID, &hQueue, szExtQueue); if (res) { printf("AM4PM not running\n"); return 2; } if (pData != NULL) { DosAllocSharedMem(&pItem, NULL, ulLen, PAG_COMMIT | OBJ_GIVEABLE | PAG_READ | PAG_WRITE); memcpy(pItem, pData, ulLen); DosGiveSharedMem(pItem, ulPID, PAG_READ | PAG_WRITE); DosFreeMem(pItem); } else pItem=NULL; res=DosWriteQueue(hQueue, usEvent, ulLen, pItem, 0); DosCloseQueue(hQueue); if (res) return 2; return 0; }
void ap_mpm_child_main(apr_pool_t *pconf) { ap_listen_rec *lr = NULL; int requests_this_child = 0; int rv = 0; unsigned long ulTimes; int my_pid = getpid(); ULONG rc, c; HQUEUE workq; apr_pollset_t *pollset; int num_listeners; TID server_maint_tid; void *sb_mem; /* Stop Ctrl-C/Ctrl-Break signals going to child processes */ DosSetSignalExceptionFocus(0, &ulTimes); set_signals(); /* Create pool for child */ apr_pool_create(&pchild, pconf); ap_run_child_init(pchild, ap_server_conf); /* Create an event semaphore used to trigger other threads to shutdown */ rc = DosCreateEventSem(NULL, &shutdown_event, 0, FALSE); if (rc) { ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf, "unable to create shutdown semaphore, exiting"); clean_child_exit(APEXIT_CHILDFATAL); } /* Gain access to the scoreboard. */ rc = DosGetNamedSharedMem(&sb_mem, ap_scoreboard_fname, PAG_READ|PAG_WRITE); if (rc) { ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf, "scoreboard not readable in child, exiting"); clean_child_exit(APEXIT_CHILDFATAL); } ap_calc_scoreboard_size(); ap_init_scoreboard(sb_mem); /* Gain access to the accpet mutex */ rc = DosOpenMutexSem(NULL, &ap_mpm_accept_mutex); if (rc) { ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf, "accept mutex couldn't be accessed in child, exiting"); clean_child_exit(APEXIT_CHILDFATAL); } /* Find our pid in the scoreboard so we know what slot our parent allocated us */ for (child_slot = 0; ap_scoreboard_image->parent[child_slot].pid != my_pid && child_slot < HARD_SERVER_LIMIT; child_slot++); if (child_slot == HARD_SERVER_LIMIT) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, "child pid not found in scoreboard, exiting"); clean_child_exit(APEXIT_CHILDFATAL); } ap_my_generation = ap_scoreboard_image->parent[child_slot].generation; memset(ap_scoreboard_image->servers[child_slot], 0, sizeof(worker_score) * HARD_THREAD_LIMIT); /* Set up an OS/2 queue for passing connections & termination requests * to worker threads */ rc = DosCreateQueue(&workq, QUE_FIFO, apr_psprintf(pchild, "/queues/httpd/work.%d", my_pid)); if (rc) { ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf, "unable to create work queue, exiting"); clean_child_exit(APEXIT_CHILDFATAL); } /* Create initial pool of worker threads */ for (c = 0; c < ap_min_spare_threads; c++) { // ap_scoreboard_image->servers[child_slot][c].tid = _beginthread(worker_main, NULL, 128*1024, (void *)c); } /* Start maintenance thread */ server_maint_tid = _beginthread(server_maintenance, NULL, 32768, NULL); /* Set up poll */ for (num_listeners = 0, lr = ap_listeners; lr; lr = lr->next) { num_listeners++; } apr_pollset_create(&pollset, num_listeners, pchild, 0); for (lr = ap_listeners; lr != NULL; lr = lr->next) { apr_pollfd_t pfd = { 0 }; pfd.desc_type = APR_POLL_SOCKET; pfd.desc.s = lr->sd; pfd.reqevents = APR_POLLIN; pfd.client_data = lr; apr_pollset_add(pollset, &pfd); } /* Main connection accept loop */ do { apr_pool_t *pconn; worker_args_t *worker_args; int last_poll_idx = 0; apr_pool_create(&pconn, pchild); worker_args = apr_palloc(pconn, sizeof(worker_args_t)); worker_args->pconn = pconn; if (num_listeners == 1) { rv = apr_socket_accept(&worker_args->conn_sd, ap_listeners->sd, pconn); } else { const apr_pollfd_t *poll_results; apr_int32_t num_poll_results; rc = DosRequestMutexSem(ap_mpm_accept_mutex, SEM_INDEFINITE_WAIT); if (shutdown_pending) { DosReleaseMutexSem(ap_mpm_accept_mutex); break; } rv = APR_FROM_OS_ERROR(rc); if (rv == APR_SUCCESS) { rv = apr_pollset_poll(pollset, -1, &num_poll_results, &poll_results); DosReleaseMutexSem(ap_mpm_accept_mutex); } if (rv == APR_SUCCESS) { if (last_poll_idx >= num_listeners) { last_poll_idx = 0; } lr = poll_results[last_poll_idx++].client_data; rv = apr_socket_accept(&worker_args->conn_sd, lr->sd, pconn); last_poll_idx++; } } if (rv != APR_SUCCESS) { if (!APR_STATUS_IS_EINTR(rv)) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, "apr_socket_accept"); clean_child_exit(APEXIT_CHILDFATAL); } } else { DosWriteQueue(workq, WORKTYPE_CONN, sizeof(worker_args_t), worker_args, 0); requests_this_child++; } if (ap_max_requests_per_child != 0 && requests_this_child >= ap_max_requests_per_child) break; } while (!shutdown_pending && ap_my_generation == ap_scoreboard_image->global->running_generation); ap_scoreboard_image->parent[child_slot].quiescing = 1; DosPostEventSem(shutdown_event); DosWaitThread(&server_maint_tid, DCWW_WAIT); if (is_graceful) { char someleft; /* tell our worker threads to exit */ for (c=0; c<HARD_THREAD_LIMIT; c++) { if (ap_scoreboard_image->servers[child_slot][c].status != SERVER_DEAD) { DosWriteQueue(workq, WORKTYPE_EXIT, 0, NULL, 0); } } do { someleft = 0; for (c=0; c<HARD_THREAD_LIMIT; c++) { if (ap_scoreboard_image->servers[child_slot][c].status != SERVER_DEAD) { someleft = 1; DosSleep(1000); break; } } } while (someleft); } else { DosPurgeQueue(workq); for (c=0; c<HARD_THREAD_LIMIT; c++) { if (ap_scoreboard_image->servers[child_slot][c].status != SERVER_DEAD) { DosKillThread(ap_scoreboard_image->servers[child_slot][c].tid); } } } apr_pool_destroy(pchild); }
/****************************************************************\ * Main client window procedure *-------------------------------------------------------------- * * Name: MainWndProc(hwnd, msg, mp1, mp2) * * Purpose: Processes the messages sent to the main client * window. This routine processes the basic * messages all client windows should process * and passes all others onto WinDefWindowProc. * * Usage: Called for each message placed in the main * window's message queue * * Method: a switch statement branches to the routines to be * performed for each message processed. * * Returns: Return values are determined by each message * \****************************************************************/ MRESULT EXPENTRY MainWndProc(HWND hwnd, /* handle of window */ ULONG msg, /* id of message */ MPARAM mp1, /* first message parameter */ MPARAM mp2) /* second message parameter */ { QDATA *pqdataQ; switch(msg) { case WM_CREATE: return InitMainWindow(hwnd, mp1, mp2); break; case WM_PAINT: MainPaint(hwnd, SvrQMsgs, iIndex, sTotalMsgs); break; case WM_SIZE: MainSize(hwnd, sTotalMsgs, mp1, mp2); break; case WM_HSCROLL: MainHorizScroll(hwnd, mp2); break; case WM_VSCROLL: MainVertScroll(hwnd, mp2); break; case WM_CHAR: switch (SHORT2FROMMP(mp2)) { case VK_LEFT: case VK_RIGHT: return MainCharHScroll (hwnd, msg, mp1, mp2) ; case VK_UP: case VK_DOWN: case VK_PAGEUP: case VK_PAGEDOWN: return MainCharVScroll (hwnd, msg, mp1, mp2) ; } break ; case WM_COMMAND: MainCommand(mp1, mp2); break; case HM_QUERY_KEYS_HELP: return (MRESULT)PANEL_HELPKEYS; /* return id of key help panel */ break ; case WM_NEWQMSG: /* copy message into circular array, with index being next free spot in array */ pqdataQ = (QDATA *)PVOIDFROMMP(mp1); sprintf(SvrQMsgs[iIndex], "Process ID: %03lu, Priority: %02hu, Message: %s", pqdataQ->pidProcess, pqdataQ->usPriority, pqdataQ->pszMsg); /* increment index, or reset to 0 as appropriate */ iIndex = (iIndex < MAX_MESSAGES - 1) ? iIndex + 1 : 0; /* increment total message count until buffer is filled */ sTotalMsgs = min(MAX_MESSAGES, sTotalMsgs + 1); MainUpdateMsg(hwnd, SvrQMsgs, iIndex, sTotalMsgs); break; case WM_MSG: MessageBox(hwndMain, (ULONG)SHORT1FROMMP(mp1), MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL, TRUE); break; case WM_CLOSE: DosWriteQueue(hqQ, WM_CLOSE, 0UL, NULL, 15UL); /* process the WM_CLOSE */ /*--------------------------------------------------*\ * Any messages not processed are passed on * to WinDefWindowProc. \*--------------------------------------------------*/ default: return WinDefWindowProc(hwnd, msg, mp1, mp2); break; } return MRFROMLONG(0L); /* all window procedures should return 0 as a default */ } /* MainWndProc() */
void os2KbdMonitorThread(void* arg) { struct KeyPacket packet; APIRET rc; USHORT length,print_flag; ULONG queueParam; HMONITOR hKbdMonitor; MONIN monInbuf; MONOUT monOutbuf; char queueName[128]; #if 0 monInbuf=(MONIN *)_tmalloc(2*sizeof(MONIN)); if (monInbuf==NULL) { xf86Msg(X_ERROR, "Could not allocate memory in kbd monitor thread!\n"); exit(1); } monOutbuf=(MONOUT *) &monInbuf[1]; #endif monInbuf.cb=sizeof(MONIN); monOutbuf.cb=sizeof(MONOUT); rc = DosMonOpen("KBD$",&hKbdMonitor); xf86Msg(X_INFO,"Opened kbd monitor, rc=%d\n",rc); rc = DosMonReg(hKbdMonitor, (PBYTE)&monInbuf,(PBYTE)&monOutbuf,(USHORT)2,(USHORT)-1); xf86Msg(X_INFO,"Kbd monitor registered, rc=%d\n",rc); if (rc) { DosMonClose(hKbdMonitor); exit(1); } /* create a queue */ sprintf(queueName,"\\QUEUES\\XF86KBD\\%d",getpid()); rc = DosCreateQueue(&hKbdQueue,0L,queueName); xf86Msg(X_INFO,"Kbd Queue created, rc=%d\n",rc); (void)DosPurgeQueue(hKbdQueue); while (1) { length = sizeof(packet); rc = DosMonRead((PBYTE)&monInbuf,0,(PBYTE)&packet,&length); if (rc) { xf86Msg(X_ERROR, "DosMonRead returned bad RC! rc=%d\n",rc); DosMonClose(hKbdMonitor); exit(1); } queueParam = packet.mnflags+(packet.ddflags<<16); if (packet.mnflags&0x7F00) DosWriteQueue(hKbdQueue,queueParam,0L,NULL,0L); /*xf86Msg(X_INFO,"Wrote a char to queue, rc=%d\n",rc); */ print_flag = packet.ddflags & 0x1F; /*xf86Msg(X_INFO,"Kbd Monitor: Key press %d, scan code %d, ddflags %d\n", packet.mnflags&0x8000,(packet.mnflags&0x7F00)>>8,packet.ddflags); */ /* This line will swallow print-screen keypresses */ if (print_flag == 0x13 || print_flag == 0x14 || print_flag == 0x15 || print_flag == 0x16) rc = 0; else rc = DosMonWrite((PBYTE)&monOutbuf,(PBYTE)&packet,length); if (rc) { xf86Msg(X_ERROR, "DosMonWrite returned bad RC! rc=%d\n",rc); DosMonClose(hKbdMonitor); exit(1); } } DosCloseQueue(hKbdQueue); DosMonClose(hKbdMonitor); }
ULONG QueueWrite( PUCHAR name, ULONG argc, PRXSTRING args, PSZ queue, PRXSTRING result) { HQUEUE handle; PQueue q; PCH dataString; ULONG length; PVOID data; ULONG request; ULONG priority; APIRET rc; ULONG cc; if (argc < 2 || argc > 4) return QUEUE_BADPARAM; if (!RxStringToUnsigned(args + 0, &handle)) return QUEUE_BADPARAM; q = (PQueue)handle; if (!RxStringIsValid(args + 1)) return QUEUE_BADPARAM; dataString = args[1].strptr; length = args[1].strlength; if (argc > 2 && RxStringIsPresent(args + 2)) { if (!RxStringToUnsigned(args + 2, &request)) return QUEUE_BADPARAM; } else request = 0; if (argc > 3 && RxStringIsPresent(args + 3)) { if (!RxStringToUnsigned(args + 3, &priority)) return QUEUE_BADPARAM; } else priority = 0; if (q->server == q->client) { data = malloc(length); if (data == NULL) return QUEUE_NOMEM; memcpy(data, dataString, length); rc = NO_ERROR; } else { rc = DosAllocSharedMem( &data, NULL, length, PAG_COMMIT | PAG_WRITE | PAG_READ | OBJ_GIVEABLE); if (rc != NO_ERROR) return QUEUE_NOMEM; memcpy(data, dataString, length); rc = DosGiveSharedMem(data, q->server, PAG_READ | PAG_WRITE); } if (rc == NO_ERROR) { rc = DosWriteQueue(q->handle, request, length, data, priority); if (rc == ERROR_SYS_INTERNAL) rc = NO_ERROR; } if (q->server != q->client) DosFreeMem(data); else if (rc != NO_ERROR) free(data); cc = UnsignedToRxResult(rc, result); return cc; }
int main (int argc, char *argv[]) { HQUEUE hq_server, hq_client; ULONG rc, len; PID owner_pid; PVOID data; REQUESTDATA request; BYTE priority; char buffer[1024], name[512], *p; long client_pid; if (argc == 1) { if (spawnl (P_NOWAIT, argv[0], argv[0], "-r", NULL) < 0) { perror ("spawn"); return (1); } for (;;) { if (fgets (buffer, sizeof (buffer), stdin) == 0) return (0); p = buffer; while (*p != 0 && !(*p >= '0' && *p <= '9')) ++p; client_pid = strtol (p, NULL, 10); (void)sprintf (name, "/queues/emacs/clients/%ld", client_pid); rc = DosOpenQueue (&owner_pid, &hq_client, name); if (rc == 0) { len = strlen (buffer) + 1; rc = DosAllocSharedMem (&data, 0, len, PAG_COMMIT | OBJ_GIVEABLE | PAG_READ | PAG_WRITE); ERROR ("DosAllocSharedMem"); rc = DosGiveSharedMem (data, client_pid, PAG_READ); ERROR ("DosGiveSharedMem"); (void)memcpy (data, buffer, len); rc = DosWriteQueue (hq_client, 0, len, data, 0); ERROR ("DosWriteQueue"); rc = DosFreeMem (data); ERROR ("DosFreeMem"); rc = DosCloseQueue (hq_client); ERROR ("DosCloseQueue"); } } } else if (argc == 2 && strcmp (argv[1], "-r") == 0) { rc = DosCreateQueue (&hq_server, QUE_FIFO | QUE_CONVERT_ADDRESS, "/queues/emacs/server"); ERROR ("DosCreateQueue"); for (;;) { rc = DosReadQueue (hq_server, &request, &len, &data, 0, DCWW_WAIT, &priority, 0); ERROR ("DosReadQueue"); (void)printf ("Client: %d ", (int)request.pid); (void)fputs (data, stdout); (void)fflush (stdout); rc = DosFreeMem (data); ERROR ("DosFreeMem"); } } else { (void)fprintf (stderr, "Usage: %s\n", argv[0]); return (1); } }
int EXPENTRY icqIPCSendCommand(ULONG uin, ICQQUEUEBLOCK *cmd) { /* Envia um comando */ char buffer[0x0100]; int rc = 0; PID pid; HQUEUE queue; ICQQUEUEBLOCK *shr; int f; char *src; char *dst; USHORT status; REQUESTDATA req; int sz; if(cmd->szPrefix != sizeof(ICQQUEUEBLOCK) || cmd->sz < sizeof(ICQQUEUEBLOCK)) return ERROR_INVALID_PARAMETER; if(!uin) { rc = icqIPCQueryInstance(&uin); if(rc) return rc; } sz = cmd->sz; /* Abre a fila */ sprintf(buffer,"\\QUEUES\\PWICQ\\%lu",uin); rc = DosOpenQueue ( &pid,&queue, buffer); if(rc) return rc; rc = DosAllocSharedMem((PVOID) &shr, NULL, sz, PAG_COMMIT|OBJ_GETTABLE|PAG_READ|PAG_WRITE); if(!rc) { DBGTracex(shr); src = (char *) cmd; dst = (char *) shr; for(f=0;f<sz;f++) *(dst++) = *(src++); rc = DosWriteQueue(queue, 0, sizeof(ULONG), (PVOID) shr, 0); if(!rc) { DBGMessage("Mensagem escrita na fila"); for(f=0;f<100 && shr->status == cmd->status;f++) DosSleep(10); DBGTrace(shr->status == cmd->status); src = (char *) shr; dst = (char *) cmd; for(f=0;f<sz;f++) *(dst++) = *(src++); } DosFreeMem(shr); } DosCloseQueue(queue); return rc; }