Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide proper operation between interps for c-vfs #23

Merged
merged 2 commits into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
2024-06-03 Konstantin Kushnir <[email protected]>
* Provide proper operation between interps for c-vfs

2024-06-02 Konstantin Kushnir <[email protected]>
* Don't allow deleting pages/fsindex that are in use
* Optimize c-readerchannel
Expand Down
4 changes: 2 additions & 2 deletions generic/fsindex.c
Original file line number Diff line number Diff line change
Expand Up @@ -339,12 +339,12 @@ Cookfs_Fsindex *Cookfs_FsindexGetHandle(Tcl_Interp *interp, const char *cmdName)
*----------------------------------------------------------------------
*/

Cookfs_Fsindex *Cookfs_FsindexInit(Cookfs_Fsindex *i) {
Cookfs_Fsindex *Cookfs_FsindexInit(Tcl_Interp *interp, Cookfs_Fsindex *i) {
Cookfs_Fsindex *rc;
if (i == NULL) {
rc = (Cookfs_Fsindex *) ckalloc(sizeof(Cookfs_Fsindex));
rc->commandToken = NULL;
rc->interp = NULL;
rc->interp = interp;
rc->isDead = 0;
rc->isLocked = 0;
} else {
Expand Down
2 changes: 1 addition & 1 deletion generic/fsindex.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ typedef struct Cookfs_Fsindex {

Cookfs_Fsindex *Cookfs_FsindexGetHandle(Tcl_Interp *interp, const char *cmdName);

Cookfs_Fsindex *Cookfs_FsindexInit(Cookfs_Fsindex *i);
Cookfs_Fsindex *Cookfs_FsindexInit(Tcl_Interp *interp, Cookfs_Fsindex *i);
void Cookfs_FsindexFini(Cookfs_Fsindex *i);
void Cookfs_FsindexCleanup(Cookfs_Fsindex *i);

Expand Down
26 changes: 21 additions & 5 deletions generic/fsindexCmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,27 @@ int Cookfs_InitFsindexCmd(Tcl_Interp *interp) {

Tcl_Obj *CookfsGetFsindexObjectCmd(Tcl_Interp *interp, Cookfs_Fsindex *i) {
if (i == NULL) {
CookfsLog(printf("CookfsGetFsindexObjectCmd: return NULL"));
return NULL;
}
CookfsRegisterExistingFsindexObjectCmd(interp, i);
CookfsLog(printf("CookfsGetFsindexObjectCmd: enter interp:%p my interp:%p",
(void *)interp, (void *)i->interp));
CookfsRegisterExistingFsindexObjectCmd(i->interp, i);
Tcl_Obj *rc = Tcl_NewObj();
Tcl_GetCommandFullName(interp, i->commandToken, rc);
Tcl_GetCommandFullName(i->interp, i->commandToken, rc);
if (interp == i->interp) {
goto done;
}
const char *cmd = Tcl_GetString(rc);
if (Tcl_GetAliasObj(interp, cmd, NULL, NULL, NULL, NULL) == TCL_OK) {
CookfsLog(printf("CookfsGetFsindexObjectCmd: alias already exists"));
goto done;
}
CookfsLog(printf("CookfsGetFsindexObjectCmd: create interp alias"));
Tcl_CreateAlias(interp, cmd, i->interp, cmd, 0, NULL);
done:
CookfsLog(printf("CookfsGetFsindexObjectCmd: return [%s]",
Tcl_GetString(rc)));
return rc;
}

Expand Down Expand Up @@ -151,10 +167,10 @@ static int CookfsRegisterFsindexObjectCmd(ClientData clientData, Tcl_Interp *int

/* import fsindex from specified data if specified, otherwise create new fsindex */
if (objc == 2) {
i = Cookfs_FsindexFromObject(NULL, objv[1]);
i = Cookfs_FsindexFromObject(interp, NULL, objv[1]);
CookfsLog(printf("CookfsRegisterFsindexObjectCmd: created fsindex from obj [%p]", (void *)i));
} else {
i = Cookfs_FsindexInit(NULL);
i = Cookfs_FsindexInit(interp, NULL);
CookfsLog(printf("CookfsRegisterFsindexObjectCmd: created fsindex from scratch [%p]", (void *)i));
}

Expand Down Expand Up @@ -404,7 +420,7 @@ static int CookfsFsindexCmdImport(Cookfs_Fsindex *fsIndex, Tcl_Interp *interp, i
return TCL_ERROR;
}

Cookfs_Fsindex *result = Cookfs_FsindexFromObject(fsIndex, objv[2]);
Cookfs_Fsindex *result = Cookfs_FsindexFromObject(interp, fsIndex, objv[2]);

return (result == NULL ? TCL_ERROR : TCL_OK);
}
Expand Down
10 changes: 5 additions & 5 deletions generic/fsindexIO.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ Tcl_Obj *Cookfs_FsindexToObject(Cookfs_Fsindex *fsindex) {
*----------------------------------------------------------------------
*/

Cookfs_Fsindex *Cookfs_FsindexFromPages(Cookfs_Fsindex *fsindex, Cookfs_Pages *pages) {
Cookfs_Fsindex *Cookfs_FsindexFromPages(Tcl_Interp *interp, Cookfs_Fsindex *fsindex, Cookfs_Pages *pages) {

CookfsLog(printf("Cookfs_FsindexFromPages: fsindex [%p] pages [%p]",
(void *)fsindex, (void *)pages));
Expand All @@ -112,11 +112,11 @@ Cookfs_Fsindex *Cookfs_FsindexFromPages(Cookfs_Fsindex *fsindex, Cookfs_Pages *p

if (indexDataLen) {
CookfsLog(printf("Cookfs_FsindexFromPages: import from the object..."));
rc = Cookfs_FsindexFromObject(fsindex, indexDataObj);
rc = Cookfs_FsindexFromObject(interp, fsindex, indexDataObj);
} else {
if (fsindex == NULL) {
CookfsLog(printf("Cookfs_FsindexFromPages: create a new clean index"));
rc = Cookfs_FsindexInit(NULL);
rc = Cookfs_FsindexInit(interp, NULL);
} else {
rc = fsindex;
Cookfs_FsindexCleanup(rc);
Expand Down Expand Up @@ -148,7 +148,7 @@ Cookfs_Fsindex *Cookfs_FsindexFromPages(Cookfs_Fsindex *fsindex, Cookfs_Pages *p
*----------------------------------------------------------------------
*/

Cookfs_Fsindex *Cookfs_FsindexFromObject(Cookfs_Fsindex *fsindex, Tcl_Obj *o) {
Cookfs_Fsindex *Cookfs_FsindexFromObject(Tcl_Interp *interp, Cookfs_Fsindex *fsindex, Tcl_Obj *o) {
Tcl_Size objLength;
int i;
unsigned char *bytes;
Expand All @@ -162,7 +162,7 @@ Cookfs_Fsindex *Cookfs_FsindexFromObject(Cookfs_Fsindex *fsindex, Tcl_Obj *o) {
}

/* initialize empty fsindex */
result = Cookfs_FsindexInit(fsindex);
result = Cookfs_FsindexInit(interp, fsindex);

if (result == NULL) {
CookfsLog(printf("Cookfs_FsindexFromObject - unable to initialize Fsindex object"))
Expand Down
4 changes: 2 additions & 2 deletions generic/fsindexIO.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
#ifdef COOKFS_USECFSINDEX

Tcl_Obj *Cookfs_FsindexToObject(Cookfs_Fsindex *fsindex);
Cookfs_Fsindex *Cookfs_FsindexFromObject(Cookfs_Fsindex *fsindex, Tcl_Obj *o);
Cookfs_Fsindex *Cookfs_FsindexFromObject(Tcl_Interp *interp, Cookfs_Fsindex *fsindex, Tcl_Obj *o);
#ifdef COOKFS_USECPAGES
Cookfs_Fsindex *Cookfs_FsindexFromPages(Cookfs_Fsindex *fsindex, Cookfs_Pages *pages);
Cookfs_Fsindex *Cookfs_FsindexFromPages(Tcl_Interp *interp, Cookfs_Fsindex *fsindex, Cookfs_Pages *pages);
#endif /* COOKFS_USECPAGES */

#endif /* COOKFS_USECFSINDEX */
Expand Down
21 changes: 18 additions & 3 deletions generic/pagesCmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,27 @@ int Cookfs_InitPagesCmd(Tcl_Interp *interp) {

Tcl_Obj *CookfsGetPagesObjectCmd(Tcl_Interp *interp, Cookfs_Pages *p) {
if (p == NULL) {
CookfsLog(printf("CookfsGetPagesObjectCmd: return NULL"));
return NULL;
}
CookfsRegisterExistingPagesObjectCmd(interp, p);
CookfsLog(printf("CookfsGetPagesObjectCmd: enter interp:%p my interp:%p",
(void *)interp, (void *)p->interp));
CookfsRegisterExistingPagesObjectCmd(p->interp, p);
Tcl_Obj *rc = Tcl_NewObj();
Tcl_GetCommandFullName(interp, p->commandToken, rc);
CookfsLog(printf("CookfsGetPagesObjectCmd: return [%p]", (void *)rc));
Tcl_GetCommandFullName(p->interp, p->commandToken, rc);
if (interp == p->interp) {
goto done;
}
const char *cmd = Tcl_GetString(rc);
if (Tcl_GetAliasObj(interp, cmd, NULL, NULL, NULL, NULL) == TCL_OK) {
CookfsLog(printf("CookfsGetPagesObjectCmd: alias already exists"));
goto done;
}
CookfsLog(printf("CookfsGetPagesObjectCmd: create interp alias"));
Tcl_CreateAlias(interp, cmd, p->interp, cmd, 0, NULL);
done:
CookfsLog(printf("CookfsGetPagesObjectCmd: return [%s]",
Tcl_GetString(rc)));
return rc;
}

Expand Down
41 changes: 40 additions & 1 deletion generic/vfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,10 +291,49 @@ void Cookfs_VfsSetReadonly(Cookfs_Vfs *vfs, int status) {
return;
}

Tcl_Obj *CookfsGetVfsObjectCmd(Cookfs_Vfs *vfs) {
Tcl_Obj *CookfsGetVfsObjectCmd(Tcl_Interp* interp, Cookfs_Vfs *vfs) {
CookfsLog(printf("CookfsGetVfsObjectCmd: enter interp:%p my interp:%p",
(void *)interp, (void *)vfs->interp));
Tcl_Obj *rc = Tcl_NewObj();
if (vfs->commandToken != NULL) {
Tcl_GetCommandFullName(vfs->interp, vfs->commandToken, rc);
if (interp == vfs->interp) {
goto done;
}
const char *cmd = Tcl_GetString(rc);
if (Tcl_GetAliasObj(interp, cmd, NULL, NULL, NULL, NULL) == TCL_OK) {
CookfsLog(printf("CookfsGetVfsObjectCmd: alias already exists"));
goto done;
}
CookfsLog(printf("CookfsGetVfsObjectCmd: create interp alias"));
Tcl_CreateAlias(interp, cmd, vfs->interp, cmd, 0, NULL);
// Create aliases for pages/fsindex commands as well. This is necessary
// for correct operation of getpages/getindex subcommands. When mount
// handler is called via an alias, it gets its own interp as a parameter.
// I.e. when it tries to provide command names for pages/fsindex,
// it provides them in own interp. There is no way to know that mount
// handler was invoked via interp alias. Thus, we will create
// pages/fsindex aliases right now.
Tcl_Obj *tmp;
if (vfs->pages != NULL) {
tmp = CookfsGetPagesObjectCmd(interp, vfs->pages);
// Release the temporary object
if (tmp != NULL) {
Tcl_IncrRefCount(tmp);
Tcl_DecrRefCount(tmp);
}
}
tmp = CookfsGetFsindexObjectCmd(interp, vfs->index);
// Release the temporary object
if (tmp != NULL) {
Tcl_IncrRefCount(tmp);
Tcl_DecrRefCount(tmp);
}
done:
CookfsLog(printf("CookfsGetVfsObjectCmd: return [%s]",
Tcl_GetString(rc)));
} else {
CookfsLog(printf("CookfsGetVfsObjectCmd: return empty result"));
}
return rc;
}
2 changes: 1 addition & 1 deletion generic/vfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,6 @@ void Cookfs_VfsUnregisterInTclvfs(Cookfs_Vfs *vfs);
int Cookfs_VfsRegisterInTclvfs(Cookfs_Vfs *vfs);
#endif

Tcl_Obj *CookfsGetVfsObjectCmd(Cookfs_Vfs *vfs);
Tcl_Obj *CookfsGetVfsObjectCmd(Tcl_Interp* interp, Cookfs_Vfs *vfs);

#endif /* COOKFS_VFS_H */
6 changes: 3 additions & 3 deletions generic/vfsCmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,9 +457,9 @@ int Cookfs_Mount(Tcl_Interp *interp, Tcl_Obj *archive, Tcl_Obj *local,
#endif
CookfsLog(printf("Cookfs_Mount: creating the index object"));
if (pages == NULL) {
index = Cookfs_FsindexInit(NULL);
index = Cookfs_FsindexInit(interp, NULL);
} else {
index = Cookfs_FsindexFromPages(NULL, pages);
index = Cookfs_FsindexFromPages(interp, NULL, pages);
}
if (index == NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj("Unable to create"
Expand Down Expand Up @@ -1046,7 +1046,7 @@ static int CookfsMountHandleCommandAside(Cookfs_Vfs *vfs, Tcl_Interp *interp,
}

CookfsLog(printf("CookfsMountHandleCommandAside: refresh index..."));
if (Cookfs_FsindexFromPages(vfs->index, vfs->pages) == NULL) {
if (Cookfs_FsindexFromPages(interp, vfs->index, vfs->pages) == NULL) {
return TCL_ERROR;
}

Expand Down
2 changes: 1 addition & 1 deletion generic/vfsDriver.c
Original file line number Diff line number Diff line change
Expand Up @@ -936,7 +936,7 @@ static int CookfsFileAttrsGet(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr,
(cookfsInternalRep *)Tcl_FSGetInternalRep(pathPtr,
&cookfsFilesystem);
if (internalRep != NULL) {
*objPtrRef = CookfsGetVfsObjectCmd(internalRep->vfs);
*objPtrRef = CookfsGetVfsObjectCmd(interp, internalRep->vfs);
CookfsLog(printf("CookfsFileAttrsGet: return value for -handle"));
return TCL_OK;
}
Expand Down
Loading