From pauljohn32 at gmail.com  Sat Feb  2 22:02:12 2013
From: pauljohn32 at gmail.com (Paul Johnson)
Date: Sat, 2 Feb 2013 15:02:12 -0600
Subject: [Rd] best practice for packages using mclapply to avoid tcltk
Message-ID: <CAErODj_1hg8+x5SvOmoL8V9RMNgMAN_fXGBLcsJhgnH_k2jOgw@mail.gmail.com>

Dear R-devel friends:

I'm back to bother you again about the conflict between mclapply and
tcltk. I've been
monitoring several packages that want to use mclapply to parallelize
computations and
need to figure out what should be done.

It appears tcltk cannot be safely unloaded, so the best we can do is
check for the presence of tcltk and stop if it is found before
mclapply() is used.

I wish you would please review my suggestion below.  Maybe checkForTcltk()
could be used in the parallel package. Otherwise, we are letting
people run with scissors.

There's a warning about this in ?mclapply

It is _strongly discouraged_ to use these functions in GUI or
    embedded environments, because it leads to several processes
    sharing the same GUI which will likely cause chaos (and possibly
    crashes).  Child processes should never use on-screen graphics
    devices.(Warning in ?mclapply)

Bug report: (https://bugs.r-project.org/bugzilla3/show_bug.cgi?id=15040 )

By the way, what is "embedded environments" in ?mclapply

## I don't want to crash your system, but if you want to see a freeze-up:
## change 0 to 1 and run this:
if (0){
library(parallel)
library(tcltk)
example(mclapply)
}

## What are packagers supposed to do if they want to call mclapply?
## It appears to me the best a package can do is scan for tcltk and
## stop. Here's a function that does so.

checkForTcltk <- function(){
    if ("tcltk" %in% loadedNamespaces()){
        stop("This function cannot be used because the R tcltk
    package is loaded. It is necessary to Close R, and re-run
    the program making sure that tcltk is never loaded before
    this function is called.")
    }
}

## put that to use.
MCLApply <- function(){
    if (!require(parallel)) stop ("parallel wouldn't load")
    checkForTcltk()
    example(mclapply)
}

## test that:

checkForTcltk()
MCLApply()

library(tcltk)
checkForTcltk()


## Why can't tcltk just be unloaded? I don't understand, but it is a deep
## problem.

## Consider the ominous warnings in R detach's help:
##
## "Unloading some namespaces has undesirable side effects: e.g.
##  unloading ?grid? closes all graphics devices, and on most systems
##  ?tcltk? cannot be reloaded once it has been unloaded and may crash
##  R if this is attempted." (Note: section of ?detach).
##
## To be fair, that does not say unloading tcltk is fatal, but
## reloading it is fatal. And I've seen plenty of times when
## unloading it is fatal.

## Example 1. Crash on library.dynam.unload()
detach("package:tcltk", unload = TRUE)
library.dynam.unload("tcltk", system.file(package = "tcltk"))

## Output
## > library.dynam.unload("tcltk", system.file(package = "tcltk"))
## >
##  *** caught segfault ***
## address 0x7f69c9d99580, cause 'memory not mapped'

## Possible actions:
## 1: abort (with core dump, if enabled)
## 2: normal R exit
## 3: exit R without saving workspace
## 4: exit R saving workspace
## Selection:
## Process R segmentation fault at Sat Feb  2 13:55:08 2013


## Example 2.
library(tcltk)
detach("package:tcltk", unload = TRUE)
library.dynam.unload("tcltk", system.file(package = "tcltk"))
example(mclapply)

## Output:

## > example(mclapply)

##  *** caught segfault ***
## address 0x7f25ccbfe000, cause 'memory not mapped'

## Possible actions:
## 1: abort (with core dump, if enabled)
## 2: normal R exit
## 3: exit R without saving workspace
## 4: exit R saving workspace
## Selection:


pj

-- 
Paul E. Johnson
Professor, Political Science      Assoc. Director
1541 Lilac Lane, Room 504      Center for Research Methods
University of Kansas                 University of Kansas
http://pj.freefaculty.org               http://quant.ku.edu



[Rd] best practice for packages using mclapply to avoid tcltk
Paul Johnson