void HgfsInitRequestList(HgfsSuperInfo *sip) // IN: Pointer to superinfo structure { int i; DEBUG(VM_DEBUG_REQUEST, "HgfsInitRequestList().\n"); ASSERT(sip); mutex_init(&sip->reqMutex, NULL, MUTEX_DRIVER, NULL); /* Initialize free request list */ DblLnkLst_Init(&sip->reqFreeList); mutex_init(&sip->reqFreeMutex, NULL, MUTEX_DRIVER, NULL); cv_init(&sip->reqFreeCondVar, NULL, CV_DRIVER, NULL); /* * Initialize pool of requests * * Here we are setting each request's id to its index into the requestPool * so this can be used as an identifier in reply packets. Each request's * state is also set to UNUSED and is added to the free list. */ for (i = 0; i < ARRAYSIZE(requestPool); i++) { requestPool[i].id = i; requestPool[i].state = HGFS_REQ_UNUSED; DblLnkLst_Init(&requestPool[i].listNode); DblLnkLst_LinkLast(&sip->reqFreeList, &requestPool[i].listNode); } //HgfsDebugPrintReqList(&sip->reqFreeList); DEBUG(VM_DEBUG_REQUEST, "HgfsInitRequestList() done.\n"); }
Bool HgfsServerPolicy_Init(HgfsInvalidateObjectsFunc invalidateObjects, // Unused HgfsRegisterSharedFolderFunc registerFolder, // Unused HgfsServerResEnumCallbacks *enumResources) // OUT enum callbacks { HgfsSharedFolder *rootShare; /* * Currently these callbacks are not used, so make sure our caller doesn't pass * it in. */ ASSERT(invalidateObjects == NULL); ASSERT(registerFolder == NULL); DblLnkLst_Init(&myState.shares); /* For the guest, we hard code a "root" share */ rootShare = (HgfsSharedFolder *)malloc(sizeof *rootShare); if (!rootShare) { LOG(4, ("HgfsServerPolicy_Init: memory allocation failed\n")); return FALSE; } DblLnkLst_Init(&rootShare->links); /* * A path = "" has special meaning; it indicates that access is * granted to the root of the server filesystem, and in Win32 * causes everything after the share name in the request to be * interpreted as either a drive letter or UNC name. [bac] */ rootShare->path = ""; rootShare->name = HGFS_SERVER_POLICY_ROOT_SHARE_NAME; rootShare->readAccess = TRUE; rootShare->writeAccess = TRUE; /* These are strictly optimizations to save work later */ rootShare->pathLen = strlen(rootShare->path); rootShare->nameLen = strlen(rootShare->name); rootShare->handle = HGFS_INVALID_FOLDER_HANDLE; /* Add the root node to the end of the list */ DblLnkLst_LinkLast(&myState.shares, &rootShare->links); /* * Fill the share enumeration callback table. */ enumResources->init = HgfsServerPolicyEnumSharesInit; enumResources->get = HgfsServerPolicyEnumSharesGet; enumResources->exit = HgfsServerPolicyEnumSharesExit; return TRUE; }
void HgfsDestroyReq(HgfsSuperInfo *sip, // IN: Superinfo containing free list HgfsReq *oldReq) // IN: Request to destroy { DEBUG(VM_DEBUG_ENTRY, "HgfsDestroyReq().\n"); /* XXX This should go away later, just for testing */ if (oldReq->state != HGFS_REQ_COMPLETED) { DEBUG(VM_DEBUG_ALWAYS, "HgfsDestroyReq() (oldReq state=%d).\n", oldReq->state); } ASSERT(sip); ASSERT(oldReq); /* Failure of this check indicates an error in program logic */ ASSERT(oldReq->state == HGFS_REQ_COMPLETED || oldReq->state == HGFS_REQ_ABANDONED || oldReq->state == HGFS_REQ_ERROR); /* * To make the request available for other clients we change its state to * UNUSED and place it back on the free list. */ mutex_enter(&sip->reqFreeMutex); oldReq->state = HGFS_REQ_UNUSED; DblLnkLst_LinkLast(&sip->reqFreeList, &oldReq->listNode); /* Wake up clients waiting for a request structure */ cv_signal(&sip->reqFreeCondVar); mutex_exit(&sip->reqFreeMutex); HgfsDebugPrintReqList(&sip->reqFreeList); DEBUG(VM_DEBUG_REQUEST, "HgfsDestroyReq() done.\n"); }
/* Test code entry point */ int main(int argc, // IN char **argv) // IN { member *c1; member *c2; member *c3; member *c4; DblLnkLst_Links h; member *a1; member *a2; member *a3; printf("Circular list: there is no origin\n"); /* Create the 1st member */ c1 = make_member(1); /* Special case: there is no list to merge with, initially */ /* Add the 2nd member _after_ the 1st one */ c2 = make_member(2); DblLnkLst_Link(&c1->l, &c2->l); /* Add the 3rd member _after_ the 2nd one */ c3 = make_member(3); DblLnkLst_Link(&c1->l, &c3->l); /* Add the 4th member _before_ the 3rd one */ c4 = make_member(4); DblLnkLst_Link(&c3->l, &c4->l); printf("See it from this member...\n"); dump_circular(c1); printf("...Or from this one\n"); dump_circular(c4); printf("\n"); printf("Anchored (linear) list: it has a beginning and an end\n"); /* Create the 'head' of the list */ DblLnkLst_Init(&h); /* Add the 1st member at the _end_ */ a1 = make_member(5); DblLnkLst_LinkLast(&h, &a1->l); /* Add the 2nd member at the _beginning_ */ a2 = make_member(6); DblLnkLst_LinkFirst(&h, &a2->l); /* Add the 3rd member _before_ the 1st one */ a3 = make_member(7); DblLnkLst_Link(&a1->l, &a3->l); dump_anchored(&h); printf("\n"); printf("Merge both lists: the result is an anchored list\n"); DblLnkLst_Link(&h, &c4->l); dump_anchored(&h); printf("\n"); printf("Remove a member\n"); DblLnkLst_Unlink1(&c3->l); dump_anchored(&h); printf("\n"); printf("Split the result in two lists: an anchored one and a circular " "one\n"); DblLnkLst_Unlink(&h, &a1->l); dump_anchored(&h); dump_circular(a1); return 0; }